It is enabled with the new --fastopen option.
doc = "";
};
+flag = {
+ name = fastopen;
+ descrip = "Enable TCP Fast Open";
+ doc = "";
+};
+
flag = {
name = x509fmtder;
descrip = "Use DER format for certificates to read from";
#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>
#include <gnutls/openpgp.h>
#include <gnutls/pkcs11.h>
#include <gnutls/crypto.h>
+#include <gnutls/socket.h>
/* Gnulib portability files. */
#include <read-file.h>
int record_max_size;
int fingerprint;
int crlf;
+int fastopen;
unsigned int verbose = 0;
int print_cert;
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));
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))
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;
{
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,
freeaddrinfo(socket->addr_info);
socket->addr_info = socket->ptr = NULL;
+ socket->connect_addrlen = 0;
free(socket->ip);
free(socket->hostname);
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;
#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;
}
#include <gnutls/gnutls.h>
+#include <gnutls/socket.h>
typedef struct {
int fd;
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;
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);