Add source port option for DTLS
authorSteven Ihde <steve@x2.hamachi.us>
Sun, 24 Jun 2012 03:49:32 +0000 (20:49 -0700)
committerDavid Woodhouse <David.Woodhouse@intel.com>
Mon, 25 Jun 2012 20:10:04 +0000 (22:10 +0200)
Signed-off-by: Steven Ihde <sihde@hamachi.us>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
dtls.c
main.c
openconnect-internal.h
openconnect.8.in
www/changelog.xml

diff --git a/dtls.c b/dtls.c
index d1862f0..30351ee 100644 (file)
--- 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 fe102ff..4495c9e 100644 (file)
--- 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();
                }
index 8fc5859..83419cb 100644 (file)
@@ -273,6 +273,8 @@ struct openconnect_info {
        struct sockaddr *peer_addr;
        struct sockaddr *dtls_addr;
 
+       int dtls_local_port;
+
        int deflate;
        char *useragent;
 
index 6cd689d..eb40d51 100644 (file)
@@ -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
index dda57fd..8b1b70a 100644 (file)
@@ -17,6 +17,7 @@
 <ul>
    <li><b>OpenConnect HEAD</b>
      <ul>
+       <li>Add <tt>--dtls-local-port</tt> option.</li>
        <li>Print correct error when <tt>/dev/net/tun</tt> cannot be opened.</li>
        <li>Fix <tt>openconnect.pc</tt> pkg-config file not to require <tt>zlib.pc</tt> on systems which lack it (like RHEL5).</li>
      </ul><br/>