summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Ruehsen <tim.ruehsen@gmx.de>2016-07-25 13:04:11 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2016-07-26 14:23:55 +0200
commite9b7e84870bc1bfea4969a57d15e523133b46ecb (patch)
tree5a4fdd04b3dcb311ffebf2292a9ac9c405c28c47
parent0f67ccecddbe6533b51e74c955a4629654e79ae3 (diff)
downloadgnutls-e9b7e84870bc1bfea4969a57d15e523133b46ecb.tar.gz
gnutls-cli: added example usage of TCP fastopen
It is enabled with the new --fastopen option.
-rw-r--r--src/cli-args.def6
-rw-r--r--src/cli.c31
-rw-r--r--src/socket.c22
-rw-r--r--src/socket.h7
4 files changed, 55 insertions, 11 deletions
diff --git a/src/cli-args.def b/src/cli-args.def
index 96e11073ad..451f80f293 100644
--- a/src/cli-args.def
+++ b/src/cli-args.def
@@ -122,6 +122,12 @@ flag = {
};
flag = {
+ name = fastopen;
+ descrip = "Enable TCP Fast Open";
+ doc = "";
+};
+
+flag = {
name = x509fmtder;
descrip = "Use DER format for certificates to read from";
doc = "";
diff --git a/src/cli.c b/src/cli.c
index 6e87abdc99..98d1c598e0 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -41,6 +41,11 @@
#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,
diff --git a/src/socket.c b/src/socket.c
index bbb97f1fd4..35fd61534e 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -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;
}
diff --git a/src/socket.h b/src/socket.h
index 4928065f3b..1f1394f812 100644
--- a/src/socket.h
+++ b/src/socket.h
@@ -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);