]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
gnutls-cli: added example usage of TCP fastopen
authorTim Ruehsen <tim.ruehsen@gmx.de>
Mon, 25 Jul 2016 11:04:11 +0000 (13:04 +0200)
committerNikos Mavrogiannopoulos <nmav@redhat.com>
Tue, 26 Jul 2016 12:23:55 +0000 (14:23 +0200)
It is enabled with the new --fastopen option.

src/cli-args.def
src/cli.c
src/socket.c
src/socket.h

index 96e11073ad271f4988faf3af3092850e59dca7b9..451f80f2931fe96eb2630bf0ac75032ac346c852 100644 (file)
@@ -121,6 +121,12 @@ flag = {
     doc      = "";
 };
 
+flag = {
+    name      = fastopen;
+    descrip   = "Enable TCP Fast Open";
+    doc      = "";
+};
+
 flag = {
     name      = x509fmtder;
     descrip   = "Use DER format for certificates to read from";
index 6e87abdc991928a19bc7464239a0938547276ebe..98d1c598e09c408c236749d7df89a43bb7a884e9 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
 #include <netdb.h>
 #include <ctype.h>
 
+/* Get TCP_FASTOPEN */
+#ifdef HAVE_NETINET_TCP_H
+#include <netinet/tcp.h>
+#endif
+
 #include <gnutls/gnutls.h>
 #include <gnutls/abstract.h>
 #include <gnutls/dtls.h>
@@ -48,6 +53,7 @@
 #include <gnutls/openpgp.h>
 #include <gnutls/pkcs11.h>
 #include <gnutls/crypto.h>
+#include <gnutls/socket.h>
 
 /* Gnulib portability files. */
 #include <read-file.h>
@@ -78,6 +84,7 @@ char service[32]="";
 int record_max_size;
 int fingerprint;
 int crlf;
+int fastopen;
 unsigned int verbose = 0;
 int print_cert;
 
@@ -908,7 +915,7 @@ static int try_resume(socket_st * hd)
 
        printf
            ("\n\n- Connecting again- trying to resume previous session\n");
-       socket_open(hd, hostname, service, udp, CONNECT_MSG);
+       socket_open(hd, hostname, service, udp | (fastopen << 1), CONNECT_MSG);
 
        if (HAVE_OPT(STARTTLS_PROTO))
                socket_starttls(hd, OPT_ARG(STARTTLS_PROTO));
@@ -1211,7 +1218,7 @@ int main(int argc, char **argv)
 
        canonicalize_host(hostname, service, sizeof(service));
 
-       socket_open(&hd, hostname, service, udp, CONNECT_MSG);
+       socket_open(&hd, hostname, service, udp | (fastopen << 1), CONNECT_MSG);
        hd.verbose = verbose;
 
        if (HAVE_OPT(STARTTLS_PROTO))
@@ -1623,6 +1630,15 @@ static void cmd_parser(int argc, char **argv)
 
        crlf = HAVE_OPT(CRLF);
 
+#ifdef TCP_FASTOPEN
+       fastopen = HAVE_OPT(FASTOPEN);
+#else
+       if (HAVE_OPT(FASTOPEN)) {
+               fprintf(stderr, "TCP Fast Open not supported for this OS\n");
+               exit(1);
+       }
+#endif
+
        if (rest != NULL)
                hostname = rest;
 
@@ -1658,8 +1674,15 @@ static int do_handshake(socket_st * socket)
 {
        int ret;
 
-       gnutls_transport_set_int(socket->session, socket->fd);
-       set_read_funcs(socket->session);
+       if (fastopen && socket->connect_addrlen) {
+               gnutls_transport_set_fastopen(socket->session, socket->fd,
+                                             (struct sockaddr*)&socket->connect_addr,
+                                             socket->connect_addrlen);
+               socket->connect_addrlen = 0;
+       } else {
+               gnutls_transport_set_int(socket->session, socket->fd);
+               set_read_funcs(socket->session);
+       }
 
        do {
                gnutls_handshake_set_timeout(socket->session,
index bbb97f1fd4815dc1931c7ff73b6f4837ebbb8ed2..35fd61534ebd4f356b4fb2aa721aac829434345c 100644 (file)
@@ -318,6 +318,7 @@ void socket_bye(socket_st * socket)
 
        freeaddrinfo(socket->addr_info);
        socket->addr_info = socket->ptr = NULL;
+       socket->connect_addrlen = 0;
 
        free(socket->ip);
        free(socket->hostname);
@@ -353,10 +354,12 @@ void canonicalize_host(char *hostname, char *service, unsigned service_size)
 
 void
 socket_open(socket_st * hd, const char *hostname, const char *service,
-           int udp, const char *msg)
+           int flags, const char *msg)
 {
        struct addrinfo hints, *res, *ptr;
        int sd, err = 0;
+       int udp = flags & 1;
+       int fastopen = flags & 2;
        char buffer[MAX_BUF + 1];
        char portname[16] = { 0 };
        char *a_hostname = (char*)hostname;
@@ -416,14 +419,21 @@ socket_open(socket_st * hd, const char *hostname, const char *service,
 #endif
                }
 
+               if (fastopen && ptr->ai_socktype == SOCK_STREAM
+                   && (ptr->ai_family == AF_INET || ptr->ai_family == AF_INET6)) {
+                       memcpy(&hd->connect_addr, ptr->ai_addr, ptr->ai_addrlen);
+                       hd->connect_addrlen = ptr->ai_addrlen;
 
-               if (msg)
-                       printf("%s '%s:%s'...\n", msg, buffer, portname);
+                       if (msg)
+                               printf("%s '%s:%s' (TFO)...\n", msg, buffer, portname);
+               } else {
+                       if (msg)
+                               printf("%s '%s:%s'...\n", msg, buffer, portname);
 
-               err = connect(sd, ptr->ai_addr, ptr->ai_addrlen);
-               if (err < 0) {
-                       continue;
+                       if ((err = connect(sd, ptr->ai_addr, ptr->ai_addrlen)) < 0)
+                               continue;
                }
+
                break;
        }
 
index 4928065f3b41ac21d0a3e11097d34e2e1c8c0ef6..1f1394f812eade95543450fc5e8326e0eb5618ea 100644 (file)
@@ -1,4 +1,5 @@
 #include <gnutls/gnutls.h>
+#include <gnutls/socket.h>
 
 typedef struct {
        int fd;
@@ -11,6 +12,10 @@ typedef struct {
        struct addrinfo *addr_info;
        int verbose;
 
+       /* Needed for TCP Fast Open */
+       struct sockaddr_storage connect_addr;
+       socklen_t connect_addrlen;
+
        /* resumption data */
        gnutls_datum_t rdata;
 } socket_st;
@@ -24,7 +29,7 @@ ssize_t socket_send(const socket_st * socket, const void *buffer,
 ssize_t socket_send_range(const socket_st * socket, const void *buffer,
                          int buffer_size, gnutls_range_st * range);
 void socket_open(socket_st * hd, const char *hostname, const char *service,
-                int udp, const char *msg);
+                int flags, const char *msg);
 
 void socket_starttls(socket_st * hd, const char *app_proto);
 void socket_bye(socket_st * socket);