From a750105dbb29636ef6e1b984846c443e6f8496ed Mon Sep 17 00:00:00 2001 From: Steven Ihde Date: Sat, 23 Jun 2012 20:49:32 -0700 Subject: [PATCH] Add source port option for DTLS Signed-off-by: Steven Ihde Signed-off-by: David Woodhouse --- dtls.c | 31 +++++++++++++++++++++++++++++++ main.c | 6 ++++++ openconnect-internal.h | 2 ++ openconnect.8.in | 6 ++++++ www/changelog.xml | 1 + 5 files changed, 46 insertions(+) diff --git a/dtls.c b/dtls.c index d1862f0a..30351eef 100644 --- a/dtls.c +++ b/dtls.c @@ -492,6 +492,37 @@ int connect_dtls_socket(struct openconnect_info *vpninfo) return -EINVAL; } + if (vpninfo->dtls_local_port) { + struct sockaddr_storage dtls_bind_addr; + int dtls_bind_addrlen; + memset(&dtls_bind_addr, 0, sizeof(dtls_bind_addr)); + + if (vpninfo->peer_addr->sa_family == AF_INET) { + struct sockaddr_in *addr = (struct sockaddr_in *)&dtls_bind_addr; + dtls_bind_addrlen = sizeof(*addr); + addr->sin_family = AF_INET; + addr->sin_addr.s_addr = INADDR_ANY; + addr->sin_port = htons(vpninfo->dtls_local_port); + } else if (vpninfo->peer_addr->sa_family == AF_INET6) { + struct sockaddr_in6 *addr = (struct sockaddr_in6 *)&dtls_bind_addr; + dtls_bind_addrlen = sizeof(*addr); + addr->sin6_family = AF_INET6; + addr->sin6_addr = in6addr_any; + addr->sin6_port = htons(vpninfo->dtls_local_port); + } else { + vpn_progress(vpninfo, PRG_ERR, + _("Unknown protocol family %d. Cannot do DTLS\n"), + vpninfo->peer_addr->sa_family); + vpninfo->dtls_attempt_period = 0; + return -EINVAL; + } + + if (bind(dtls_fd, (struct sockaddr *)&dtls_bind_addr, dtls_bind_addrlen)) { + perror(_("Bind UDP socket for DTLS")); + return -EINVAL; + } + } + if (connect(dtls_fd, vpninfo->dtls_addr, vpninfo->peer_addrlen)) { perror(_("UDP (DTLS) connect:\n")); close(dtls_fd); diff --git a/main.c b/main.c index fe102fff..4495c9e7 100644 --- a/main.c +++ b/main.c @@ -107,6 +107,7 @@ enum { OPT_SERVERCERT, OPT_USERAGENT, OPT_NON_INTER, + OPT_DTLS_LOCAL_PORT, }; #ifdef __sun__ @@ -169,6 +170,7 @@ static struct option long_options[] = { OPTION("no-cert-check", 0, OPT_NO_CERT_CHECK), OPTION("force-dpd", 1, OPT_FORCE_DPD), OPTION("non-inter", 0, OPT_NON_INTER), + OPTION("dtls-local-port", 1, OPT_DTLS_LOCAL_PORT), OPTION(NULL, 0, 0) }; @@ -273,6 +275,7 @@ static void usage(void) printf(" --reconnect-timeout %s\n", _("Connection retry timeout in seconds")); printf(" --servercert=FINGERPRINT %s\n", _("Server's certificate SHA1 fingerprint")); printf(" --useragent=STRING %s\n", _("HTTP header User-Agent: field")); + printf(" --dtls-local-port=PORT %s\n", _("Set local port for DTLS datagrams")); printf("\n"); helpmessage(); @@ -684,6 +687,9 @@ int main(int argc, char **argv) case OPT_FORCE_DPD: vpninfo->dtls_times.dpd = vpninfo->ssl_times.dpd = atoi(config_arg); break; + case OPT_DTLS_LOCAL_PORT: + vpninfo->dtls_local_port = atoi(config_arg); + break; default: usage(); } diff --git a/openconnect-internal.h b/openconnect-internal.h index 8fc5859e..83419cb0 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -273,6 +273,8 @@ struct openconnect_info { struct sockaddr *peer_addr; struct sockaddr *dtls_addr; + int dtls_local_port; + int deflate; char *useragent; diff --git a/openconnect.8.in b/openconnect.8.in index 6cd689d6..eb40d515 100644 --- a/openconnect.8.in +++ b/openconnect.8.in @@ -42,6 +42,7 @@ openconnect \- Connect to Cisco AnyConnect VPN .OP \-\-cafile file .OP \-\-disable\-ipv6 .OP \-\-dtls\-ciphers list +.OP \-\-dtls\-local\-port port .OP \-\-no\-cert\-check .OP \-\-no\-dtls .OP \-\-no\-http\-keepalive @@ -335,6 +336,11 @@ Use .I STRING as 'User\-Agent:' field value in HTTP header. (e.g. \-\-useragent 'Cisco AnyConnect VPN Agent for Windows 2.2.0133') +.TP +.B \-\-dtls\-local\-port=PORT +Use +.I PORT +as the local port for DTLS datagrams .SH LIMITATIONS Note that although IPv6 has been tested on all platforms on which diff --git a/www/changelog.xml b/www/changelog.xml index dda57fdd..8b1b70aa 100644 --- a/www/changelog.xml +++ b/www/changelog.xml @@ -17,6 +17,7 @@
  • OpenConnect HEAD
      +
    • Add --dtls-local-port option.
    • Print correct error when /dev/net/tun cannot be opened.
    • Fix openconnect.pc pkg-config file not to require zlib.pc on systems which lack it (like RHEL5).