Browse code

svn merge -r 618:619 $SO/patches/openvpn-2-0_rc16-mh/openvpn Merged --multihome patch + aggregated sockflags. Pre-2.1_beta3

git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@622 e7ae566f-a301-0410-adde-c780ea21d3b5

james authored on 2005/10/15 17:44:02
Showing 20 changed files
... ...
@@ -11,12 +11,11 @@ $Id$
11 11
   from the file specified by --ca regardless if the pkcs12 file
12 12
   contains a CA cert or not (Mathias Sundman).
13 13
 * Merged --capath patch (Thomas Noel).
14
-* NOTE TO PACKAGE MAINTAINERS: Moved "plugin"
15
-  directory to "plugins".  This is
16
-  to work around a strange problem with the
17
-  "make dist" target in the automake-generated
18
-  makefile, where the target tries to do a
19
-  rather bogus "gcc -g -O2 -I. plugin.c -o plugin".
14
+* Merged --multihome patch.
15
+* NOTE TO PACKAGE MAINTAINERS: Moved "plugin" directory to "plugins".
16
+  This is to work around a strange problem with the "make dist"
17
+  target in the automake-generated makefile, where the target tries to
18
+  do a rather bogus "gcc -g -O2 -I. plugin.c -o plugin".
20 19
 
21 20
 2005.10.13 -- Version 2.1-beta2
22 21
 
... ...
@@ -95,6 +95,12 @@ AC_ARG_ENABLE(fragment,
95 95
    [FRAGMENT="yes"]
96 96
 )
97 97
 
98
+AC_ARG_ENABLE(multihome,
99
+   [  --disable-multihome     Disable multi-homed UDP server support (--multihome)],
100
+   [MULTIHOME="$enableval"],
101
+   [MULTIHOME="yes"]
102
+)
103
+
98 104
 AC_ARG_ENABLE(debug,
99 105
    [  --disable-debug         Disable debugging support (disable gremlin and verb 7+ messages)],
100 106
    [DEBUG="$enableval"],
... ...
@@ -342,6 +348,11 @@ AC_CHECK_TYPE(
342 342
 	[AC_DEFINE(HAVE_CMSGHDR, 1, [struct cmsghdr needed for extended socket error support])],
343 343
 	[],
344 344
 	[#include "syshead.h"])
345
+AC_CHECK_TYPE(
346
+	[struct in_pktinfo],
347
+	[AC_DEFINE(HAVE_IN_PKTINFO, 1, [struct in_pktinfo needed for IP_PKTINFO support])],
348
+	[],
349
+	[#include "syshead.h"])
345 350
 
346 351
 AC_CHECK_SIZEOF(unsigned int)
347 352
 AC_CHECK_SIZEOF(unsigned long)
... ...
@@ -367,7 +378,7 @@ AC_CHECK_FUNCS(daemon chroot getpwnam setuid nice system getpid dup dup2 dnl
367 367
 	       getpass strerror syslog openlog mlockall getgrnam setgid dnl
368 368
 	       setgroups stat flock readv writev setsockopt getsockopt dnl
369 369
 	       setsid chdir gettimeofday putenv getpeername unlink dnl
370
-               poll chsize ftruncate)
370
+               poll chsize ftruncate sendmsg recvmsg)
371 371
 AC_CACHE_SAVE
372 372
 
373 373
 dnl Required library functions
... ...
@@ -605,6 +616,11 @@ if test "$HTTP_PROXY" = "yes"; then
605 605
    AC_DEFINE(ENABLE_HTTP_PROXY, 1, [Enable HTTP proxy support])
606 606
 fi
607 607
 
608
+dnl compile --multihome option
609
+if test "$MULTIHOME" = "yes"; then
610
+   AC_DEFINE(ENABLE_MULTIHOME, 1, [Enable multi-homed UDP server capability])
611
+fi
612
+
608 613
 dnl enable debugging
609 614
 if test "$DEBUG" = "yes"; then
610 615
    AC_DEFINE(ENABLE_DEBUG, 1, [Enable debugging support])
... ...
@@ -571,12 +571,12 @@ socks_postprocess_incoming_link (struct context *c)
571 571
 
572 572
 static inline void
573 573
 socks_preprocess_outgoing_link (struct context *c,
574
-				struct sockaddr_in **to_addr,
574
+				struct link_socket_actual **to_addr,
575 575
 				int *size_delta)
576 576
 {
577 577
   if (c->c2.link_socket->socks_proxy && c->c2.link_socket->info.proto == PROTO_UDPv4)
578 578
     {
579
-      *size_delta += socks_process_outgoing_udp (&c->c2.to_link, &c->c2.to_link_addr);
579
+      *size_delta += socks_process_outgoing_udp (&c->c2.to_link, c->c2.to_link_addr);
580 580
       *to_addr = &c->c2.link_socket->socks_relay;
581 581
     }
582 582
 }
... ...
@@ -616,7 +616,10 @@ read_incoming_link (struct context *c)
616 616
   c->c2.buf = c->c2.buffers->read_link_buf;
617 617
   ASSERT (buf_init (&c->c2.buf, FRAME_HEADROOM_ADJ (&c->c2.frame, FRAME_HEADROOM_MARKER_READ_LINK)));
618 618
 
619
-  status = link_socket_read (c->c2.link_socket, &c->c2.buf, MAX_RW_SIZE_LINK (&c->c2.frame), &c->c2.from);
619
+  status = link_socket_read (c->c2.link_socket,
620
+			     &c->c2.buf,
621
+			     MAX_RW_SIZE_LINK (&c->c2.frame),
622
+			     &c->c2.from);
620 623
 
621 624
   if (socket_connection_reset (c->c2.link_socket, status))
622 625
     {
... ...
@@ -687,7 +690,7 @@ process_incoming_link (struct context *c)
687 687
   msg (D_LINK_RW, "%s READ [%d] from %s: %s",
688 688
        proto2ascii (lsi->proto, true),
689 689
        BLEN (&c->c2.buf),
690
-       print_sockaddr (&c->c2.from, &gc),
690
+       print_link_socket_actual (&c->c2.from, &gc),
691 691
        PROTO_DUMP (&c->c2.buf, &gc));
692 692
 
693 693
   /*
... ...
@@ -985,7 +988,7 @@ process_outgoing_link (struct context *c)
985 985
        * packet to remote over the TCP/UDP port.
986 986
        */
987 987
       int size = 0;
988
-      ASSERT (addr_defined (&c->c2.to_link_addr));
988
+      ASSERT (link_socket_actual_defined (c->c2.to_link_addr));
989 989
 
990 990
 #ifdef ENABLE_DEBUG
991 991
       /* In gremlin-test mode, we may choose to drop this packet */
... ...
@@ -1020,12 +1023,12 @@ process_outgoing_link (struct context *c)
1020 1020
 	  msg (D_LINK_RW, "%s WRITE [%d] to %s: %s",
1021 1021
 	       proto2ascii (c->c2.link_socket->info.proto, true),
1022 1022
 	       BLEN (&c->c2.to_link),
1023
-	       print_sockaddr (&c->c2.to_link_addr, &gc),
1023
+	       print_link_socket_actual (c->c2.to_link_addr, &gc),
1024 1024
 	       PROTO_DUMP (&c->c2.to_link, &gc));
1025 1025
 
1026 1026
 	  /* Packet send complexified by possible Socks5 usage */
1027 1027
 	  {
1028
-	    struct sockaddr_in *to_addr = &c->c2.to_link_addr;
1028
+	    struct link_socket_actual *to_addr = c->c2.to_link_addr;
1029 1029
 #ifdef ENABLE_SOCKS
1030 1030
 	    int size_delta = 0;
1031 1031
 #endif
... ...
@@ -1035,7 +1038,9 @@ process_outgoing_link (struct context *c)
1035 1035
 	    socks_preprocess_outgoing_link (c, &to_addr, &size_delta);
1036 1036
 #endif
1037 1037
 	    /* Send packet */
1038
-	    size = link_socket_write (c->c2.link_socket, &c->c2.to_link, to_addr);
1038
+	    size = link_socket_write (c->c2.link_socket,
1039
+				      &c->c2.to_link,
1040
+				      to_addr);
1039 1041
 
1040 1042
 #ifdef ENABLE_SOCKS
1041 1043
 	    /* Undo effect of prepend */
... ...
@@ -1059,7 +1064,7 @@ process_outgoing_link (struct context *c)
1059 1059
 	  if (size != BLEN (&c->c2.to_link))
1060 1060
 	    msg (D_LINK_ERRORS,
1061 1061
 		 "TCP/UDP packet was truncated/expanded on write to %s (tried=%d,actual=%d)",
1062
-		 print_sockaddr (&c->c2.to_link_addr, &gc),
1062
+		 print_link_socket_actual (c->c2.to_link_addr, &gc),
1063 1063
 		 BLEN (&c->c2.to_link),
1064 1064
 		 size);
1065 1065
 	}
... ...
@@ -1068,7 +1073,7 @@ process_outgoing_link (struct context *c)
1068 1068
     {
1069 1069
       if (c->c2.to_link.len > 0)
1070 1070
 	msg (D_LINK_ERRORS, "TCP/UDP packet too large on write to %s (tried=%d,max=%d)",
1071
-	     print_sockaddr (&c->c2.to_link_addr, &gc),
1071
+	     print_link_socket_actual (c->c2.to_link_addr, &gc),
1072 1072
 	     c->c2.to_link.len,
1073 1073
 	     EXPANDED_SIZE (&c->c2.frame));
1074 1074
     }
... ...
@@ -770,13 +770,16 @@ static void
770 770
 man_accept (struct management *man)
771 771
 {
772 772
   struct gc_arena gc = gc_new ();
773
+  struct link_socket_actual act;
773 774
 
774 775
   /*
775 776
    * Accept the TCP client.
776 777
    */
777
-  man->connection.sd_cli = socket_do_accept (man->connection.sd_top, &man->connection.remote, false);
778
+  man->connection.sd_cli = socket_do_accept (man->connection.sd_top, &act, false);
778 779
   if (socket_defined (man->connection.sd_cli))
779 780
     {
781
+      man->connection.remote = act.dest;
782
+
780 783
       if (socket_defined (man->connection.sd_top))
781 784
 	{
782 785
 #ifdef WIN32
... ...
@@ -1145,9 +1148,9 @@ man_settings_init (struct man_settings *ms,
1145 1145
       /*
1146 1146
        * Initialize socket address
1147 1147
        */
1148
-      ms->local.sin_family = AF_INET;
1149
-      ms->local.sin_addr.s_addr = 0;
1150
-      ms->local.sin_port = htons (port);
1148
+      ms->local.sa.sin_family = AF_INET;
1149
+      ms->local.sa.sin_addr.s_addr = 0;
1150
+      ms->local.sa.sin_port = htons (port);
1151 1151
 
1152 1152
       /*
1153 1153
        * Run management over tunnel, or
... ...
@@ -1159,7 +1162,7 @@ man_settings_init (struct man_settings *ms,
1159 1159
 	}
1160 1160
       else
1161 1161
 	{
1162
-	  ms->local.sin_addr.s_addr = getaddr
1162
+	  ms->local.sa.sin_addr.s_addr = getaddr
1163 1163
 	    (GETADDR_RESOLVE|GETADDR_WARN_ON_SIGNAL|GETADDR_FATAL, addr, 0, NULL, NULL);
1164 1164
 	}
1165 1165
       
... ...
@@ -1406,7 +1409,7 @@ management_post_tunnel_open (struct management *man, const in_addr_t tun_local_i
1406 1406
       && man->connection.state == MS_INITIAL)
1407 1407
     {
1408 1408
       /* listen on our local TUN/TAP IP address */
1409
-      man->settings.local.sin_addr.s_addr = htonl (tun_local_ip);
1409
+      man->settings.local.sa.sin_addr.s_addr = htonl (tun_local_ip);
1410 1410
       man_connection_init (man);
1411 1411
     }
1412 1412
 
... ...
@@ -188,7 +188,7 @@ struct man_persist {
188 188
 
189 189
 struct man_settings {
190 190
   bool defined;
191
-  struct sockaddr_in local;
191
+  struct openvpn_sockaddr local;
192 192
   bool up_query_passwords;
193 193
   bool management_over_tunnel;
194 194
   struct user_pass up;
... ...
@@ -215,7 +215,7 @@ struct man_connection {
215 215
 
216 216
   socket_descriptor_t sd_top;
217 217
   socket_descriptor_t sd_cli;
218
-  struct sockaddr_in remote;
218
+  struct openvpn_sockaddr remote;
219 219
 
220 220
 #ifdef WIN32
221 221
   struct net_event_win32 ne32;
... ...
@@ -168,28 +168,29 @@ mroute_extract_addr_from_packet (struct mroute_addr *src,
168 168
 }
169 169
 
170 170
 /*
171
- * Translate a struct sockaddr_in (saddr)
171
+ * Translate a struct openvpn_sockaddr (osaddr)
172 172
  * to a struct mroute_addr (addr).
173 173
  */
174
-bool
175
-mroute_extract_sockaddr_in (struct mroute_addr *addr, const struct sockaddr_in *saddr, bool use_port)
174
+bool mroute_extract_openvpn_sockaddr (struct mroute_addr *addr,
175
+				      const struct openvpn_sockaddr *osaddr,
176
+				      bool use_port)
176 177
 {
177
-  if (saddr->sin_family == AF_INET)
178
+  if (osaddr->sa.sin_family == AF_INET)
178 179
     {
179 180
       if (use_port)
180 181
 	{
181 182
 	  addr->type = MR_ADDR_IPV4 | MR_WITH_PORT;
182 183
 	  addr->netbits = 0;
183 184
 	  addr->len = 6;
184
-	  memcpy (addr->addr, &saddr->sin_addr.s_addr, 4);
185
-	  memcpy (addr->addr + 4, &saddr->sin_port, 2);
185
+	  memcpy (addr->addr, &osaddr->sa.sin_addr.s_addr, 4);
186
+	  memcpy (addr->addr + 4, &osaddr->sa.sin_port, 2);
186 187
 	}
187 188
       else
188 189
 	{
189 190
 	  addr->type = MR_ADDR_IPV4;
190 191
 	  addr->netbits = 0;
191 192
 	  addr->len = 4;
192
-	  memcpy (addr->addr, &saddr->sin_addr.s_addr, 4);
193
+	  memcpy (addr->addr, &osaddr->sa.sin_addr.s_addr, 4);
193 194
 	}
194 195
       return true;
195 196
     }
... ...
@@ -94,9 +94,11 @@ unsigned int mroute_extract_addr_from_packet (struct mroute_addr *src,
94 94
 					      struct buffer *buf,
95 95
 					      int tunnel_type);
96 96
 
97
-bool mroute_extract_sockaddr_in (struct mroute_addr *addr,
98
-				 const struct sockaddr_in *saddr,
99
-				 bool use_port);
97
+struct openvpn_sockaddr;
98
+
99
+bool mroute_extract_openvpn_sockaddr (struct mroute_addr *addr,
100
+				      const struct openvpn_sockaddr *osaddr,
101
+				      bool use_port);
100 102
 
101 103
 bool mroute_learnable_address (const struct mroute_addr *addr);
102 104
 
... ...
@@ -159,7 +159,7 @@ multi_tcp_instance_specific_init (struct multi_context *m, struct multi_instance
159 159
   ASSERT (mi->context.c2.link_socket);
160 160
   ASSERT (mi->context.c2.link_socket->info.lsa);
161 161
   ASSERT (mi->context.c2.link_socket->mode == LS_MODE_TCP_ACCEPT_FROM);
162
-  if (!mroute_extract_sockaddr_in (&mi->real, &mi->context.c2.link_socket->info.lsa->actual, true))
162
+  if (!mroute_extract_openvpn_sockaddr (&mi->real, &mi->context.c2.link_socket->info.lsa->actual.dest, true))
163 163
     {
164 164
       msg (D_MULTI_ERRORS, "MULTI TCP: TCP client address is undefined");
165 165
       return false;
... ...
@@ -51,7 +51,7 @@ multi_get_create_instance_udp (struct multi_context *m)
51 51
   struct multi_instance *mi = NULL;
52 52
   struct hash *hash = m->hash;
53 53
 
54
-  if (mroute_extract_sockaddr_in (&real, &m->top.c2.from, true))
54
+  if (mroute_extract_openvpn_sockaddr (&real, &m->top.c2.from.dest, true))
55 55
     {
56 56
       struct hash_element *he;
57 57
       const uint32_t hv = hash_value (hash, &real);
... ...
@@ -982,13 +982,13 @@ multi_learn_in_addr_t (struct multi_context *m,
982 982
 		       in_addr_t a,
983 983
 		       int netbits) /* -1 if host route, otherwise # of network bits in address */
984 984
 {
985
-  struct sockaddr_in remote_si;
985
+  struct openvpn_sockaddr remote_si;
986 986
   struct mroute_addr addr;
987 987
 
988 988
   CLEAR (remote_si);
989
-  remote_si.sin_family = AF_INET;
990
-  remote_si.sin_addr.s_addr = htonl (a);
991
-  ASSERT (mroute_extract_sockaddr_in (&addr, &remote_si, false));
989
+  remote_si.sa.sin_family = AF_INET;
990
+  remote_si.sa.sin_addr.s_addr = htonl (a);
991
+  ASSERT (mroute_extract_openvpn_sockaddr (&addr, &remote_si, false));
992 992
 
993 993
   if (netbits >= 0)
994 994
     {
... ...
@@ -2180,15 +2180,15 @@ management_callback_kill_by_addr (void *arg, const in_addr_t addr, const int por
2180 2180
   struct multi_context *m = (struct multi_context *) arg;
2181 2181
   struct hash_iterator hi;
2182 2182
   struct hash_element *he;
2183
-  struct sockaddr_in saddr;
2183
+  struct openvpn_sockaddr saddr;
2184 2184
   struct mroute_addr maddr;
2185 2185
   int count = 0;
2186 2186
 
2187 2187
   CLEAR (saddr);
2188
-  saddr.sin_family = AF_INET;
2189
-  saddr.sin_addr.s_addr = htonl (addr);
2190
-  saddr.sin_port = htons (port);
2191
-  if (mroute_extract_sockaddr_in (&maddr, &saddr, true))
2188
+  saddr.sa.sin_family = AF_INET;
2189
+  saddr.sa.sin_addr.s_addr = htonl (addr);
2190
+  saddr.sa.sin_port = htons (port);
2191
+  if (mroute_extract_openvpn_sockaddr (&maddr, &saddr, true))
2192 2192
     {
2193 2193
       hash_iterator_init (m->iter, &hi, true);
2194 2194
       while ((he = hash_iterator_next (&hi)))
... ...
@@ -205,8 +205,8 @@ struct context_2
205 205
   struct link_socket_info *link_socket_info;
206 206
   const struct link_socket *accept_from; /* possibly do accept() on a parent link_socket */
207 207
 
208
-  struct sockaddr_in to_link_addr;	 /* IP address of remote */
209
-  struct sockaddr_in from;               /* address of incoming datagram */
208
+  struct link_socket_actual *to_link_addr;	/* IP address of remote */
209
+  struct link_socket_actual from;               /* address of incoming datagram */
210 210
 
211 211
   /* MTU frame parameters */
212 212
   struct frame frame;
... ...
@@ -175,6 +175,9 @@ static const char usage_message[] =
175 175
   "--ping-timer-rem: Run the --ping-exit/--ping-restart timer only if we have a\n"
176 176
   "                  remote address.\n"
177 177
   "--ping n        : Ping remote once every n seconds over TCP/UDP port.\n"
178
+#if ENABLE_IP_PKTINFO
179
+  "--multihome     : Configure a multi-homed UDP server.\n"
180
+#endif
178 181
   "--fast-io       : (experimental) Optimize TUN/TAP/UDP writes.\n"
179 182
   "--remap-usr1 s  : On SIGUSR1 signals, remap signal (s='SIGHUP' or 'SIGTERM').\n"
180 183
   "--persist-tun   : Keep tun/tap device open across SIGUSR1 or --ping-restart.\n"
... ...
@@ -3281,6 +3284,13 @@ add_option (struct options *options,
3281 3281
       VERIFY_PERMISSION (OPT_P_GENERAL);
3282 3282
       options->mlock = true;
3283 3283
     }
3284
+#if ENABLE_IP_PKTINFO
3285
+  else if (streq (p[0], "multihome"))
3286
+    {
3287
+      VERIFY_PERMISSION (OPT_P_GENERAL);
3288
+      options->sockflags |= SF_USE_IP_PKTINFO;
3289
+    }
3290
+#endif
3284 3291
   else if (streq (p[0], "verb") && p[1])
3285 3292
     {
3286 3293
       ++i;
... ...
@@ -37,7 +37,7 @@ check_ping_restart (struct context *c)
37 37
       && event_timeout_trigger (&c->c2.ping_rec_interval,
38 38
 				&c->c2.timeval,
39 39
 				(!c->options.ping_timer_remote
40
-				 || addr_defined (&c->c1.link_socket_addr.actual))
40
+				 || link_socket_actual_defined (&c->c1.link_socket_addr.actual))
41 41
 				? ETT_DEFAULT : 15))
42 42
     check_ping_restart_dowork (c);
43 43
 }
... ...
@@ -236,7 +236,7 @@ openvpn_inet_aton (const char *dotted_quad, struct in_addr *addr)
236 236
 
237 237
 static void
238 238
 update_remote (const char* host,
239
-	       struct sockaddr_in *addr,
239
+	       struct openvpn_sockaddr *addr,
240 240
 	       bool *changed)
241 241
 {
242 242
   if (host && addr)
... ...
@@ -247,9 +247,9 @@ update_remote (const char* host,
247 247
 					  1,
248 248
 					  NULL,
249 249
 					  NULL);
250
-      if (new_addr && addr->sin_addr.s_addr != new_addr)
250
+      if (new_addr && addr->sa.sin_addr.s_addr != new_addr)
251 251
 	{
252
-	  addr->sin_addr.s_addr = new_addr;
252
+	  addr->sa.sin_addr.s_addr = new_addr;
253 253
 	  *changed = true;
254 254
 	}
255 255
     }
... ...
@@ -492,12 +492,19 @@ create_socket_tcp (void)
492 492
 }
493 493
 
494 494
 static socket_descriptor_t
495
-create_socket_udp (void)
495
+create_socket_udp (const unsigned int flags)
496 496
 {
497 497
   socket_descriptor_t sd;
498 498
 
499 499
   if ((sd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
500 500
     msg (M_SOCKERR, "UDP: Cannot create UDP socket");
501
+#if ENABLE_IP_PKTINFO
502
+  else if (flags & SF_USE_IP_PKTINFO)
503
+    {
504
+      int pad = 1;
505
+      setsockopt (sd, SOL_IP, IP_PKTINFO, (void*)&pad, sizeof(pad));
506
+    }
507
+#endif
501 508
   return sd;
502 509
 }
503 510
 
... ...
@@ -507,7 +514,7 @@ create_socket (struct link_socket *sock)
507 507
   /* create socket */
508 508
   if (sock->info.proto == PROTO_UDPv4)
509 509
     {
510
-      sock->sd = create_socket_udp ();
510
+      sock->sd = create_socket_udp (sock->sockflags);
511 511
 
512 512
 #ifdef ENABLE_SOCKS
513 513
       if (sock->socks_proxy)
... ...
@@ -531,7 +538,7 @@ create_socket (struct link_socket *sock)
531 531
 
532 532
 static void
533 533
 socket_do_listen (socket_descriptor_t sd,
534
-		  const struct sockaddr_in *local,
534
+		  const struct openvpn_sockaddr *local,
535 535
 		  bool do_listen,
536 536
 		  bool do_set_nonblock)
537 537
 {
... ...
@@ -553,16 +560,18 @@ socket_do_listen (socket_descriptor_t sd,
553 553
 
554 554
 socket_descriptor_t
555 555
 socket_do_accept (socket_descriptor_t sd,
556
-		  struct sockaddr_in *remote,
556
+		  struct link_socket_actual *act,
557 557
 		  const bool nowait)
558 558
 {
559
-  socklen_t remote_len = sizeof (*remote);
559
+  socklen_t remote_len = sizeof (act->dest.sa);
560 560
   socket_descriptor_t new_sd = SOCKET_UNDEFINED;
561 561
 
562
+  CLEAR (*act);
563
+
562 564
 #ifdef HAVE_GETPEERNAME
563 565
   if (nowait)
564 566
     {
565
-      new_sd = getpeername (sd, (struct sockaddr *) remote, &remote_len);
567
+      new_sd = getpeername (sd, (struct sockaddr *) &act->dest.sa, &remote_len);
566 568
 
567 569
       if (!socket_defined (new_sd))
568 570
 	msg (D_LINK_ERRORS | M_ERRNO_SOCK, "TCP: getpeername() failed");
... ...
@@ -575,14 +584,14 @@ socket_do_accept (socket_descriptor_t sd,
575 575
 #endif
576 576
   else
577 577
     {
578
-      new_sd = accept (sd, (struct sockaddr *) remote, &remote_len);
578
+      new_sd = accept (sd, (struct sockaddr *) &act->dest.sa, &remote_len);
579 579
     }
580 580
 
581 581
   if (!socket_defined (new_sd))
582 582
     {
583 583
       msg (D_LINK_ERRORS | M_ERRNO_SOCK, "TCP: accept(%d) failed", sd);
584 584
     }
585
-  else if (remote_len != sizeof (*remote))
585
+  else if (remote_len != sizeof (act->dest.sa))
586 586
     {
587 587
       msg (D_LINK_ERRORS, "TCP: Received strange incoming connection with unknown address length=%d", remote_len);
588 588
       openvpn_close_socket (new_sd);
... ...
@@ -592,28 +601,30 @@ socket_do_accept (socket_descriptor_t sd,
592 592
 }
593 593
 
594 594
 static void
595
-tcp_connection_established (const struct sockaddr_in *remote)
595
+tcp_connection_established (const struct link_socket_actual *act)
596 596
 {
597 597
   struct gc_arena gc = gc_new ();
598 598
   msg (M_INFO, "TCP connection established with %s", 
599
-       print_sockaddr (remote, &gc));
599
+       print_link_socket_actual (act, &gc));
600 600
   gc_free (&gc);
601 601
 }
602 602
 
603 603
 static int
604 604
 socket_listen_accept (socket_descriptor_t sd,
605
-		      struct sockaddr_in *remote,
605
+		      struct link_socket_actual *act,
606 606
 		      const char *remote_dynamic,
607 607
 		      bool *remote_changed,
608
-		      const struct sockaddr_in *local,
608
+		      const struct openvpn_sockaddr *local,
609 609
 		      bool do_listen,
610 610
 		      bool nowait,
611 611
 		      volatile int *signal_received)
612 612
 {
613 613
   struct gc_arena gc = gc_new ();
614
-  struct sockaddr_in remote_verify = *remote;
614
+  //struct openvpn_sockaddr *remote = &act->dest;
615
+  struct openvpn_sockaddr remote_verify = act->dest;
615 616
   int new_sd = SOCKET_UNDEFINED;
616 617
 
618
+  CLEAR (*act);
617 619
   socket_do_listen (sd, local, do_listen, true);
618 620
 
619 621
   while (true)
... ...
@@ -645,17 +656,17 @@ socket_listen_accept (socket_descriptor_t sd,
645 645
 	  continue;
646 646
 	}
647 647
 
648
-      new_sd = socket_do_accept (sd, remote, nowait);
648
+      new_sd = socket_do_accept (sd, act, nowait);
649 649
 
650 650
       if (socket_defined (new_sd))
651 651
 	{
652 652
 	  update_remote (remote_dynamic, &remote_verify, remote_changed);
653 653
 	  if (addr_defined (&remote_verify)
654
-	      && !addr_match (&remote_verify, remote))
654
+	      && !addr_match (&remote_verify, &act->dest))
655 655
 	    {
656 656
 	      msg (M_WARN,
657 657
 		   "TCP NOTE: Rejected connection attempt from %s due to --remote setting",
658
-		   print_sockaddr (remote, &gc));
658
+		   print_link_socket_actual (act, &gc));
659 659
 	      if (openvpn_close_socket (new_sd))
660 660
 		msg (M_SOCKERR, "TCP: close socket failed (new_sd)");
661 661
 	    }
... ...
@@ -668,7 +679,7 @@ socket_listen_accept (socket_descriptor_t sd,
668 668
   if (!nowait && openvpn_close_socket (sd))
669 669
     msg (M_SOCKERR, "TCP: close socket failed (sd)");
670 670
 
671
-  tcp_connection_established (remote);
671
+  tcp_connection_established (act);
672 672
 
673 673
   gc_free (&gc);
674 674
   return new_sd;
... ...
@@ -676,7 +687,7 @@ socket_listen_accept (socket_descriptor_t sd,
676 676
 
677 677
 static void
678 678
 socket_connect (socket_descriptor_t *sd,
679
-		struct sockaddr_in *remote,
679
+		struct openvpn_sockaddr *remote,
680 680
 		struct remote_list *remote_list,
681 681
 		const char *remote_dynamic,
682 682
 		bool *remote_changed,
... ...
@@ -689,8 +700,8 @@ socket_connect (socket_descriptor_t *sd,
689 689
        print_sockaddr (remote, &gc));
690 690
   while (true)
691 691
     {
692
-      const int status = connect (*sd, (struct sockaddr *) remote,
693
-				  sizeof (*remote));
692
+      const int status = connect (*sd, (struct sockaddr *) &remote->sa,
693
+				  sizeof (remote->sa));
694 694
 
695 695
       get_signal (signal_received);
696 696
       if (*signal_received)
... ...
@@ -711,7 +722,7 @@ socket_connect (socket_descriptor_t *sd,
711 711
 	{
712 712
 	  remote_list_next (remote_list);
713 713
 	  remote_dynamic = remote_list_host (remote_list);
714
-	  remote->sin_port = htons (remote_list_port (remote_list));
714
+	  remote->sa.sin_port = htons (remote_list_port (remote_list));
715 715
 	  *remote_changed = true;
716 716
 	}
717 717
 
... ...
@@ -771,22 +782,22 @@ resolve_bind_local (struct link_socket *sock)
771 771
   /* resolve local address if undefined */
772 772
   if (!addr_defined (&sock->info.lsa->local))
773 773
     {
774
-      sock->info.lsa->local.sin_family = AF_INET;
775
-      sock->info.lsa->local.sin_addr.s_addr =
774
+      sock->info.lsa->local.sa.sin_family = AF_INET;
775
+      sock->info.lsa->local.sa.sin_addr.s_addr =
776 776
 	(sock->local_host ? getaddr (GETADDR_RESOLVE | GETADDR_WARN_ON_SIGNAL | GETADDR_FATAL,
777 777
 				     sock->local_host,
778 778
 				     0,
779 779
 				     NULL,
780 780
 				     NULL)
781 781
 	 : htonl (INADDR_ANY));
782
-      sock->info.lsa->local.sin_port = htons (sock->local_port);
782
+      sock->info.lsa->local.sa.sin_port = htons (sock->local_port);
783 783
     }
784 784
   
785 785
   /* bind to local address/port */
786 786
   if (sock->bind_local)
787 787
     {
788
-      if (bind (sock->sd, (struct sockaddr *) &sock->info.lsa->local,
789
-		sizeof (sock->info.lsa->local)))
788
+      if (bind (sock->sd, (struct sockaddr *) &sock->info.lsa->local.sa,
789
+		sizeof (sock->info.lsa->local.sa)))
790 790
 	{
791 791
 	  const int errnum = openvpn_errno_socket ();
792 792
 	  msg (M_FATAL, "TCP/UDP: Socket bind failed on local address %s: %s",
... ...
@@ -810,8 +821,8 @@ resolve_remote (struct link_socket *sock,
810 810
       /* resolve remote address if undefined */
811 811
       if (!addr_defined (&sock->info.lsa->remote))
812 812
 	{
813
-	  sock->info.lsa->remote.sin_family = AF_INET;
814
-	  sock->info.lsa->remote.sin_addr.s_addr = 0;
813
+	  sock->info.lsa->remote.sa.sin_family = AF_INET;
814
+	  sock->info.lsa->remote.sa.sin_addr.s_addr = 0;
815 815
 
816 816
 	  if (sock->remote_host)
817 817
 	    {
... ...
@@ -856,7 +867,7 @@ resolve_remote (struct link_socket *sock,
856 856
 		  ASSERT (0);
857 857
 		}
858 858
 
859
-	      sock->info.lsa->remote.sin_addr.s_addr = getaddr (
859
+	      sock->info.lsa->remote.sa.sin_addr.s_addr = getaddr (
860 860
 		    flags,
861 861
 		    sock->remote_host,
862 862
 		    retry,
... ...
@@ -883,19 +894,22 @@ resolve_remote (struct link_socket *sock,
883 883
 		}
884 884
 	    }
885 885
 
886
-	  sock->info.lsa->remote.sin_port = htons (sock->remote_port);
886
+	  sock->info.lsa->remote.sa.sin_port = htons (sock->remote_port);
887 887
 	}
888 888
   
889 889
       /* should we re-use previous active remote address? */
890
-      if (addr_defined (&sock->info.lsa->actual))
890
+      if (link_socket_actual_defined (&sock->info.lsa->actual))
891 891
 	{
892 892
 	  msg (M_INFO, "TCP/UDP: Preserving recently used remote address: %s",
893
-	       print_sockaddr (&sock->info.lsa->actual, &gc));
893
+	       print_link_socket_actual (&sock->info.lsa->actual, &gc));
894 894
 	  if (remote_dynamic)
895 895
 	    *remote_dynamic = NULL;
896 896
 	}
897 897
       else
898
-	sock->info.lsa->actual = sock->info.lsa->remote;
898
+	{
899
+	  CLEAR (sock->info.lsa->actual);
900
+	  sock->info.lsa->actual.dest = sock->info.lsa->remote;
901
+	}
899 902
 
900 903
       /* remember that we finished */
901 904
       sock->did_resolve_remote = true;
... ...
@@ -1162,7 +1176,7 @@ link_socket_init_phase2 (struct link_socket *sock,
1162 1162
       else if (sock->info.proto == PROTO_TCPv4_CLIENT)
1163 1163
 	{
1164 1164
 	  socket_connect (&sock->sd,
1165
-			  &sock->info.lsa->actual,
1165
+			  &sock->info.lsa->actual.dest,
1166 1166
 			  sock->remote_list,
1167 1167
 			  remote_dynamic,
1168 1168
 			  &remote_changed,
... ...
@@ -1200,7 +1214,7 @@ link_socket_init_phase2 (struct link_socket *sock,
1200 1200
       else if (sock->info.proto == PROTO_UDPv4 && sock->socks_proxy)
1201 1201
 	{
1202 1202
 	  socket_connect (&sock->ctrl_sd,
1203
-			  &sock->info.lsa->actual,
1203
+			  &sock->info.lsa->actual.dest,
1204 1204
 			  NULL,
1205 1205
 			  remote_dynamic,
1206 1206
 			  &remote_changed,
... ...
@@ -1212,7 +1226,8 @@ link_socket_init_phase2 (struct link_socket *sock,
1212 1212
 
1213 1213
 	  establish_socks_proxy_udpassoc (sock->socks_proxy,
1214 1214
 					  sock->ctrl_sd,
1215
-					  sock->sd, &sock->socks_relay,
1215
+					  sock->sd,
1216
+					  &sock->socks_relay.dest,
1216 1217
 					  signal_received);
1217 1218
 
1218 1219
 	  if (*signal_received)
... ...
@@ -1221,8 +1236,9 @@ link_socket_init_phase2 (struct link_socket *sock,
1221 1221
 	  sock->remote_host = sock->proxy_dest_host;
1222 1222
 	  sock->remote_port = sock->proxy_dest_port;
1223 1223
 	  sock->did_resolve_remote = false;
1224
-	  sock->info.lsa->actual.sin_addr.s_addr = 0;
1225
-	  sock->info.lsa->remote.sin_addr.s_addr = 0;
1224
+
1225
+	  sock->info.lsa->actual.dest.sa.sin_addr.s_addr = 0;
1226
+	  sock->info.lsa->remote.sa.sin_addr.s_addr = 0;
1226 1227
 
1227 1228
 	  resolve_remote (sock, 1, NULL, signal_received);
1228 1229
 
... ...
@@ -1237,7 +1253,7 @@ link_socket_init_phase2 (struct link_socket *sock,
1237 1237
       if (remote_changed)
1238 1238
 	{
1239 1239
 	  msg (M_INFO, "TCP/UDP: Dynamic remote address changed during TCP connection establishment");
1240
-	  sock->info.lsa->remote.sin_addr.s_addr = sock->info.lsa->actual.sin_addr.s_addr;
1240
+	  sock->info.lsa->remote.sa.sin_addr.s_addr = sock->info.lsa->actual.dest.sa.sin_addr.s_addr;
1241 1241
 	}
1242 1242
     }
1243 1243
 
... ...
@@ -1274,12 +1290,15 @@ link_socket_init_phase2 (struct link_socket *sock,
1274 1274
     msg (M_INFO, "%s link local%s: %s",
1275 1275
 	 proto2ascii (sock->info.proto, true),
1276 1276
 	 (sock->bind_local ? " (bound)" : ""),
1277
-	 print_sockaddr_ex (&sock->info.lsa->local, sock->bind_local, ":", &gc));
1277
+	 print_sockaddr_ex (&sock->info.lsa->local, ":", sock->bind_local ? PS_SHOW_PORT : 0, &gc));
1278 1278
 
1279 1279
   /* print active remote address */
1280 1280
   msg (M_INFO, "%s link remote: %s",
1281 1281
        proto2ascii (sock->info.proto, true),
1282
-       print_sockaddr_ex (&sock->info.lsa->actual, addr_defined (&sock->info.lsa->actual), ":", &gc));
1282
+       print_link_socket_actual_ex (&sock->info.lsa->actual,
1283
+				    ":",
1284
+				    PS_SHOW_PORT_IF_DEFINED,
1285
+				    &gc));
1283 1286
 
1284 1287
  done:
1285 1288
   gc_free (&gc);
... ...
@@ -1344,19 +1363,19 @@ socket_adjust_frame_parameters (struct frame *frame, int proto)
1344 1344
 void
1345 1345
 setenv_trusted (struct env_set *es, const struct link_socket_info *info)
1346 1346
 {
1347
-  setenv_sockaddr (es, "trusted", &info->lsa->actual, SA_IP_PORT);
1347
+  setenv_link_socket_actual (es, "trusted", &info->lsa->actual, SA_IP_PORT);
1348 1348
 }
1349 1349
 
1350 1350
 void
1351 1351
 link_socket_connection_initiated (const struct buffer *buf,
1352 1352
 				  struct link_socket_info *info,
1353
-				  const struct sockaddr_in *addr,
1353
+				  const struct link_socket_actual *act,
1354 1354
 				  const char *common_name,
1355 1355
 				  struct env_set *es)
1356 1356
 {
1357 1357
   struct gc_arena gc = gc_new ();
1358 1358
   
1359
-  info->lsa->actual = *addr; /* Note: skip this line for --force-dest */
1359
+  info->lsa->actual = *act; /* Note: skip this line for --force-dest */
1360 1360
   setenv_trusted (es, info);
1361 1361
   info->connection_established = true;
1362 1362
 
... ...
@@ -1365,7 +1384,7 @@ link_socket_connection_initiated (const struct buffer *buf,
1365 1365
     struct buffer out = alloc_buf_gc (256, &gc);
1366 1366
     if (common_name)
1367 1367
       buf_printf (&out, "[%s] ", common_name);
1368
-    buf_printf (&out, "Peer Connection Initiated with %s", print_sockaddr (&info->lsa->actual, &gc));
1368
+    buf_printf (&out, "Peer Connection Initiated with %s", print_link_socket_actual (&info->lsa->actual, &gc));
1369 1369
     msg (M_INFO, "%s", BSTR (&out));
1370 1370
   }
1371 1371
 
... ...
@@ -1375,7 +1394,7 @@ link_socket_connection_initiated (const struct buffer *buf,
1375 1375
   /* Process --ipchange plugin */
1376 1376
   if (plugin_defined (info->plugins, OPENVPN_PLUGIN_IPCHANGE))
1377 1377
     {
1378
-      const char *addr_ascii = print_sockaddr_ex (&info->lsa->actual, true, " ", &gc);
1378
+      const char *addr_ascii = print_sockaddr_ex (&info->lsa->actual.dest, " ", PS_SHOW_PORT, &gc);
1379 1379
       if (plugin_call (info->plugins, OPENVPN_PLUGIN_IPCHANGE, addr_ascii, NULL, es))
1380 1380
 	msg (M_WARN, "WARNING: ipchange plugin call failed");
1381 1381
     }
... ...
@@ -1387,7 +1406,7 @@ link_socket_connection_initiated (const struct buffer *buf,
1387 1387
       setenv_str (es, "script_type", "ipchange");
1388 1388
       buf_printf (&out, "%s %s",
1389 1389
 		  info->ipchange_command,
1390
-		  print_sockaddr_ex (&info->lsa->actual, true, " ", &gc));
1390
+		  print_sockaddr_ex (&info->lsa->actual.dest, " ", PS_SHOW_PORT, &gc));
1391 1391
       system_check (BSTR (&out), es, S_SCRIPT, "ip-change command failed");
1392 1392
     }
1393 1393
 
... ...
@@ -1397,14 +1416,14 @@ link_socket_connection_initiated (const struct buffer *buf,
1397 1397
 void
1398 1398
 link_socket_bad_incoming_addr (struct buffer *buf,
1399 1399
 			       const struct link_socket_info *info,
1400
-			       const struct sockaddr_in *from_addr)
1400
+			       const struct link_socket_actual *from_addr)
1401 1401
 {
1402 1402
   struct gc_arena gc = gc_new ();
1403 1403
 
1404 1404
   msg (D_LINK_ERRORS,
1405 1405
        "TCP/UDP: Incoming packet rejected from %s[%d], expected peer address: %s (allow this incoming source address/port by removing --remote or adding --float)",
1406
-       print_sockaddr (from_addr, &gc),
1407
-       (int)from_addr->sin_family,
1406
+       print_link_socket_actual (from_addr, &gc),
1407
+       (int)from_addr->dest.sa.sin_family,
1408 1408
        print_sockaddr (&info->lsa->remote, &gc));
1409 1409
   buf->len = 0;
1410 1410
 
... ...
@@ -1422,10 +1441,10 @@ link_socket_current_remote (const struct link_socket_info *info)
1422 1422
 {
1423 1423
   const struct link_socket_addr *lsa = info->lsa;
1424 1424
 
1425
-  if (addr_defined (&lsa->actual))
1426
-    return ntohl (lsa->actual.sin_addr.s_addr);
1425
+  if (link_socket_actual_defined (&lsa->actual))
1426
+    return ntohl (lsa->actual.dest.sa.sin_addr.s_addr);
1427 1427
   else if (addr_defined (&lsa->remote))
1428
-    return ntohl (lsa->remote.sin_addr.s_addr);
1428
+    return ntohl (lsa->remote.sa.sin_addr.s_addr);
1429 1429
   else
1430 1430
     return 0;
1431 1431
 }
... ...
@@ -1618,29 +1637,69 @@ socket_listen_event_handle (struct link_socket *s)
1618 1618
  */
1619 1619
 
1620 1620
 const char *
1621
-print_sockaddr (const struct sockaddr_in *addr, struct gc_arena *gc)
1621
+print_sockaddr (const struct openvpn_sockaddr *addr, struct gc_arena *gc)
1622 1622
 {
1623
-  return print_sockaddr_ex(addr, true, ":", gc);
1623
+  return print_sockaddr_ex (addr, ":", PS_SHOW_PORT, gc);
1624 1624
 }
1625 1625
 
1626 1626
 const char *
1627
-print_sockaddr_ex (const struct sockaddr_in *addr, bool do_port, const char* separator, struct gc_arena *gc)
1627
+print_sockaddr_ex (const struct openvpn_sockaddr *addr,
1628
+		   const char* separator,
1629
+		   const unsigned int flags,
1630
+		   struct gc_arena *gc)
1628 1631
 {
1629
-  struct buffer out = alloc_buf_gc (64, gc);
1630
-  const int port = ntohs (addr->sin_port);
1632
+  if (addr)
1633
+    {
1634
+      struct buffer out = alloc_buf_gc (64, gc);
1635
+      const int port = ntohs (addr->sa.sin_port);
1631 1636
 
1632
-  mutex_lock_static (L_INET_NTOA);
1633
-  buf_printf (&out, "%s", (addr_defined (addr) ? inet_ntoa (addr->sin_addr) : "[undef]"));
1634
-  mutex_unlock_static (L_INET_NTOA);
1637
+      mutex_lock_static (L_INET_NTOA);
1638
+      buf_printf (&out, "%s", (addr_defined (addr) ? inet_ntoa (addr->sa.sin_addr) : "[undef]"));
1639
+      mutex_unlock_static (L_INET_NTOA);
1635 1640
 
1636
-  if (do_port && port)
1637
-    {
1638
-      if (separator)
1639
-	buf_printf (&out, "%s", separator);
1641
+      if (((flags & PS_SHOW_PORT) || (addr_defined (addr) && (flags & PS_SHOW_PORT_IF_DEFINED)))
1642
+	  && port)
1643
+	{
1644
+	  if (separator)
1645
+	    buf_printf (&out, "%s", separator);
1640 1646
 
1641
-      buf_printf (&out, "%d", port);
1647
+	  buf_printf (&out, "%d", port);
1648
+	}
1649
+      return BSTR (&out);
1642 1650
     }
1643
-  return BSTR (&out);
1651
+  else
1652
+    return "[NULL]";
1653
+}
1654
+
1655
+const char *
1656
+print_link_socket_actual (const struct link_socket_actual *act, struct gc_arena *gc)
1657
+{
1658
+  return print_link_socket_actual_ex (act, ":", PS_SHOW_PORT|PS_SHOW_PKTINFO, gc);
1659
+}
1660
+
1661
+const char *
1662
+print_link_socket_actual_ex (const struct link_socket_actual *act,
1663
+			     const char *separator,
1664
+			     const unsigned int flags,
1665
+			     struct gc_arena *gc)
1666
+{
1667
+  if (act)
1668
+    {
1669
+      struct buffer out = alloc_buf_gc (128, gc);
1670
+      buf_printf (&out, "%s", print_sockaddr_ex (&act->dest, separator, flags, gc));
1671
+#if ENABLE_IP_PKTINFO
1672
+      if ((flags & PS_SHOW_PKTINFO) && act->pi.ipi_spec_dst.s_addr)
1673
+	{
1674
+	  struct openvpn_sockaddr sa;
1675
+	  CLEAR (sa);
1676
+	  sa.sa.sin_addr = act->pi.ipi_spec_dst;
1677
+	  buf_printf (&out, " (via %s)", print_sockaddr_ex (&sa, separator, 0, gc));
1678
+	}
1679
+#endif
1680
+      return BSTR (&out);
1681
+    }
1682
+  else
1683
+    return "[NULL]";
1644 1684
 }
1645 1685
 
1646 1686
 /*
... ...
@@ -1667,7 +1726,7 @@ print_in_addr_t (in_addr_t addr, unsigned int flags, struct gc_arena *gc)
1667 1667
 
1668 1668
 /* set environmental variables for ip/port in *addr */
1669 1669
 void
1670
-setenv_sockaddr (struct env_set *es, const char *name_prefix, const struct sockaddr_in *addr, const bool flags)
1670
+setenv_sockaddr (struct env_set *es, const char *name_prefix, const struct openvpn_sockaddr *addr, const bool flags)
1671 1671
 {
1672 1672
   char name_buf[256];
1673 1673
 
... ...
@@ -1677,13 +1736,13 @@ setenv_sockaddr (struct env_set *es, const char *name_prefix, const struct socka
1677 1677
     openvpn_snprintf (name_buf, sizeof (name_buf), "%s", name_prefix);
1678 1678
 
1679 1679
   mutex_lock_static (L_INET_NTOA);
1680
-  setenv_str (es, name_buf, inet_ntoa (addr->sin_addr));
1680
+  setenv_str (es, name_buf, inet_ntoa (addr->sa.sin_addr));
1681 1681
   mutex_unlock_static (L_INET_NTOA);
1682 1682
 
1683
-  if ((flags & SA_IP_PORT) && addr->sin_port)
1683
+  if ((flags & SA_IP_PORT) && addr->sa.sin_port)
1684 1684
     {
1685 1685
       openvpn_snprintf (name_buf, sizeof (name_buf), "%s_port", name_prefix);
1686
-      setenv_int (es, name_buf, ntohs (addr->sin_port));
1686
+      setenv_int (es, name_buf, ntohs (addr->sa.sin_port));
1687 1687
     }
1688 1688
 }
1689 1689
 
... ...
@@ -1692,13 +1751,22 @@ setenv_in_addr_t (struct env_set *es, const char *name_prefix, in_addr_t addr, c
1692 1692
 {
1693 1693
   if (addr || !(flags & SA_SET_IF_NONZERO))
1694 1694
     {
1695
-      struct sockaddr_in si;
1695
+      struct openvpn_sockaddr si;
1696 1696
       CLEAR (si);
1697
-      si.sin_addr.s_addr = htonl (addr);
1697
+      si.sa.sin_addr.s_addr = htonl (addr);
1698 1698
       setenv_sockaddr (es, name_prefix, &si, flags);
1699 1699
     }
1700 1700
 }
1701 1701
 
1702
+void
1703
+setenv_link_socket_actual (struct env_set *es,
1704
+			   const char *name_prefix,
1705
+			   const struct link_socket_actual *act,
1706
+			   const bool flags)
1707
+{
1708
+  setenv_sockaddr (es, name_prefix, &act->dest, flags);
1709
+}
1710
+
1702 1711
 /*
1703 1712
  * Convert protocol names between index and ascii form.
1704 1713
  */
... ...
@@ -1828,19 +1896,72 @@ link_socket_read_tcp (struct link_socket *sock,
1828 1828
 
1829 1829
 #ifndef WIN32
1830 1830
 
1831
+#if ENABLE_IP_PKTINFO
1832
+
1833
+struct openvpn_pktinfo
1834
+{
1835
+  struct cmsghdr cmsghdr;
1836
+  struct in_pktinfo in_pktinfo;
1837
+};
1838
+
1839
+static socklen_t
1840
+link_socket_read_udp_posix_recvmsg (struct link_socket *sock,
1841
+				    struct buffer *buf,
1842
+				    int maxsize,
1843
+				    struct link_socket_actual *from)
1844
+{
1845
+  struct iovec iov;
1846
+  struct openvpn_pktinfo opi;
1847
+  struct msghdr mesg;
1848
+  socklen_t fromlen = sizeof (from->dest.sa);
1849
+
1850
+  iov.iov_base = BPTR (buf);
1851
+  iov.iov_len = maxsize;
1852
+  mesg.msg_iov = &iov;
1853
+  mesg.msg_iovlen = 1;
1854
+  mesg.msg_name = &from->dest.sa;
1855
+  mesg.msg_namelen = fromlen;
1856
+  mesg.msg_control = &opi;
1857
+  mesg.msg_controllen = sizeof (opi);
1858
+  buf->len = recvmsg (sock->sd, &mesg, 0);
1859
+  if (buf->len >= 0)
1860
+    {
1861
+      struct cmsghdr *cmsg;
1862
+      fromlen = mesg.msg_namelen;
1863
+      cmsg = CMSG_FIRSTHDR (&mesg);
1864
+      if (cmsg != NULL
1865
+	  && CMSG_NXTHDR (&mesg, cmsg) == NULL
1866
+	  && cmsg->cmsg_level == SOL_IP 
1867
+	  && cmsg->cmsg_type == IP_PKTINFO
1868
+	  && cmsg->cmsg_len >= sizeof (opi))
1869
+	{
1870
+	  struct in_pktinfo *pkti = (struct in_pktinfo *) CMSG_DATA (cmsg);
1871
+	  from->pi.ipi_ifindex = pkti->ipi_ifindex;
1872
+	  from->pi.ipi_spec_dst = pkti->ipi_spec_dst;
1873
+	}
1874
+    }
1875
+  return fromlen;
1876
+}
1877
+#endif
1878
+
1831 1879
 int
1832 1880
 link_socket_read_udp_posix (struct link_socket *sock,
1833 1881
 			    struct buffer *buf,
1834 1882
 			    int maxsize,
1835
-			    struct sockaddr_in *from)
1883
+			    struct link_socket_actual *from)
1836 1884
 {
1837
-  socklen_t fromlen = sizeof (*from);
1838
-  CLEAR (*from);
1885
+  socklen_t fromlen = sizeof (from->dest.sa);
1886
+  from->dest.sa.sin_addr.s_addr = 0;
1839 1887
   ASSERT (buf_safe (buf, maxsize));
1840
-  buf->len = recvfrom (sock->sd, BPTR (buf), maxsize, 0,
1841
-		       (struct sockaddr *) from, &fromlen);
1842
-  if (fromlen != sizeof (*from))
1843
-    bad_address_length (fromlen, sizeof (*from));
1888
+#if ENABLE_IP_PKTINFO
1889
+  if (sock->sockflags & SF_USE_IP_PKTINFO)
1890
+    fromlen = link_socket_read_udp_posix_recvmsg (sock, buf, maxsize, from);
1891
+  else
1892
+#endif
1893
+    buf->len = recvfrom (sock->sd, BPTR (buf), maxsize, 0,
1894
+			 (struct sockaddr *) &from->dest.sa, &fromlen);
1895
+  if (fromlen != sizeof (from->dest.sa))
1896
+    bad_address_length (fromlen, sizeof (from->dest.sa));
1844 1897
   return buf->len;
1845 1898
 }
1846 1899
 
... ...
@@ -1853,7 +1974,7 @@ link_socket_read_udp_posix (struct link_socket *sock,
1853 1853
 int
1854 1854
 link_socket_write_tcp (struct link_socket *sock,
1855 1855
 		       struct buffer *buf,
1856
-		       struct sockaddr_in *to)
1856
+		       struct link_socket_actual *to)
1857 1857
 {
1858 1858
   packet_size_type len = BLEN (buf);
1859 1859
   dmsg (D_STREAM_DEBUG, "STREAM: WRITE %d offset=%d", (int)len, buf->offset);
... ...
@@ -1867,6 +1988,41 @@ link_socket_write_tcp (struct link_socket *sock,
1867 1867
 #endif
1868 1868
 }
1869 1869
 
1870
+#if ENABLE_IP_PKTINFO
1871
+
1872
+int
1873
+link_socket_write_udp_posix_sendmsg (struct link_socket *sock,
1874
+				     struct buffer *buf,
1875
+				     struct link_socket_actual *to)
1876
+{
1877
+  struct iovec iov;
1878
+  struct msghdr mesg;
1879
+  struct cmsghdr *cmsg;
1880
+  struct in_pktinfo *pkti;
1881
+  struct openvpn_pktinfo opi;
1882
+
1883
+  iov.iov_base = BPTR (buf);
1884
+  iov.iov_len = BLEN (buf);
1885
+  mesg.msg_iov = &iov;
1886
+  mesg.msg_iovlen = 1;
1887
+  mesg.msg_name = &to->dest.sa;
1888
+  mesg.msg_namelen = sizeof (to->dest.sa);
1889
+  mesg.msg_control = &opi;
1890
+  mesg.msg_controllen = sizeof (opi);
1891
+  mesg.msg_flags = 0;
1892
+  cmsg = CMSG_FIRSTHDR (&mesg);
1893
+  cmsg->cmsg_len = sizeof (opi);
1894
+  cmsg->cmsg_level = SOL_IP;
1895
+  cmsg->cmsg_type = IP_PKTINFO;
1896
+  pkti = (struct in_pktinfo *) CMSG_DATA (cmsg);
1897
+  pkti->ipi_ifindex = to->pi.ipi_ifindex;
1898
+  pkti->ipi_spec_dst = to->pi.ipi_spec_dst;
1899
+  pkti->ipi_addr.s_addr = 0;
1900
+  return sendmsg (sock->sd, &mesg, 0);
1901
+}
1902
+
1903
+#endif
1904
+
1870 1905
 /*
1871 1906
  * Win32 overlapped socket I/O functions.
1872 1907
  */
... ...
@@ -1981,7 +2137,7 @@ socket_recv_queue (struct link_socket *sock, int maxsize)
1981 1981
 }
1982 1982
 
1983 1983
 int
1984
-socket_send_queue (struct link_socket *sock, struct buffer *buf, const struct sockaddr_in *to)
1984
+socket_send_queue (struct link_socket *sock, struct buffer *buf, const struct link_socket_actual *to)
1985 1985
 {
1986 1986
   if (sock->writes.iostate == IOSTATE_INITIAL)
1987 1987
     {
... ...
@@ -2005,7 +2161,7 @@ socket_send_queue (struct link_socket *sock, struct buffer *buf, const struct so
2005 2005
 	{
2006 2006
 	  /* set destination address for UDP writes */
2007 2007
 	  sock->writes.addr_defined = true;
2008
-	  sock->writes.addr = *to;
2008
+	  sock->writes.addr = to->dest.sa;
2009 2009
 	  sock->writes.addrlen = sizeof (sock->writes.addr);
2010 2010
 
2011 2011
 	  status = WSASendTo(
... ...
@@ -2081,11 +2237,10 @@ socket_send_queue (struct link_socket *sock, struct buffer *buf, const struct so
2081 2081
 }
2082 2082
 
2083 2083
 int
2084
-socket_finalize (
2085
-		 SOCKET s,
2084
+socket_finalize (SOCKET s,
2086 2085
 		 struct overlapped_io *io,
2087 2086
 		 struct buffer *buf,
2088
-		 struct sockaddr_in *from)
2087
+		 struct link_socket_actual *from)
2089 2088
 {
2090 2089
   int ret = -1;
2091 2090
   BOOL status;
... ...
@@ -2162,10 +2317,10 @@ socket_finalize (
2162 2162
 	{
2163 2163
 	  if (io->addrlen != sizeof (io->addr))
2164 2164
 	    bad_address_length (io->addrlen, sizeof (io->addr));
2165
-	  *from = io->addr;
2165
+	  from->dest.sa = io->addr;
2166 2166
 	}
2167 2167
       else
2168
-	CLEAR (*from);
2168
+	CLEAR (from->dest.sa);
2169 2169
     }
2170 2170
   
2171 2171
   if (buf)
... ...
@@ -77,12 +77,29 @@ typedef uint16_t packet_size_type;
77 77
 /* convert a packet_size_type from network to host order */
78 78
 #define ntohps(x) ntohs(x)
79 79
 
80
+/* OpenVPN sockaddr struct */
81
+struct openvpn_sockaddr
82
+{
83
+  int dummy; // JYFIXME
84
+  struct sockaddr_in sa;
85
+};
86
+
87
+/* actual address of remote, based on source address of received packets */
88
+struct link_socket_actual
89
+{
90
+  int dummy; // JYFIXME
91
+  struct openvpn_sockaddr dest;
92
+#if ENABLE_IP_PKTINFO
93
+  struct in_pktinfo pi;
94
+#endif
95
+};
96
+
80 97
 /* IP addresses which are persistant across SIGUSR1s */
81 98
 struct link_socket_addr
82 99
 {
83
-  struct sockaddr_in local;
84
-  struct sockaddr_in remote; /* initial remote */
85
-  struct sockaddr_in actual; /* remote may change due to --float */
100
+  struct openvpn_sockaddr local;
101
+  struct openvpn_sockaddr remote;   /* initial remote */
102
+  struct link_socket_actual actual; /* reply to this address */
86 103
 };
87 104
 
88 105
 struct link_socket_info
... ...
@@ -180,7 +197,8 @@ struct link_socket
180 180
 
181 181
   bool did_resolve_remote;
182 182
 
183
-# define SF_TCP_NODELAY (1<<0)
183
+# define SF_USE_IP_PKTINFO (1<<0)
184
+# define SF_TCP_NODELAY (1<<1)
184 185
   unsigned int sockflags;
185 186
 
186 187
   /* for stream sockets */
... ...
@@ -196,7 +214,7 @@ struct link_socket
196 196
 #ifdef ENABLE_SOCKS
197 197
   /* Socks proxy */
198 198
   struct socks_proxy_info *socks_proxy;
199
-  struct sockaddr_in socks_relay; /* Socks UDP relay address */
199
+  struct link_socket_actual socks_relay; /* Socks UDP relay address */
200 200
 #endif
201 201
 
202 202
 #if defined(ENABLE_HTTP_PROXY) || defined(ENABLE_SOCKS)
... ...
@@ -232,13 +250,13 @@ int socket_recv_queue (struct link_socket *sock, int maxsize);
232 232
 
233 233
 int socket_send_queue (struct link_socket *sock,
234 234
 		       struct buffer *buf,
235
-		       const struct sockaddr_in *to);
235
+		       const struct link_socket_actual *to);
236 236
 
237 237
 int socket_finalize (
238 238
 		     SOCKET s,
239 239
 		     struct overlapped_io *io,
240 240
 		     struct buffer *buf,
241
-		     struct sockaddr_in *from);
241
+		     struct link_socket_actual *from);
242 242
 
243 243
 #else
244 244
 
... ...
@@ -286,23 +304,34 @@ void link_socket_init_phase2 (struct link_socket *sock,
286 286
 			      const struct frame *frame,
287 287
 			      volatile int *signal_received);
288 288
 
289
-void link_socket_post_fork (const struct link_socket *sock,
290
-			    const struct sockaddr_in *remote);
291
-
292 289
 void socket_adjust_frame_parameters (struct frame *frame, int proto);
293 290
 
294 291
 void frame_adjust_path_mtu (struct frame *frame, int pmtu, int proto);
295 292
 
296 293
 void link_socket_close (struct link_socket *sock);
297 294
 
298
-const char *print_sockaddr_ex (const struct sockaddr_in *addr,
299
-			       bool do_port,
295
+#define PS_SHOW_PORT_IF_DEFINED (1<<0)
296
+#define PS_SHOW_PORT            (1<<1)
297
+#define PS_SHOW_PKTINFO         (1<<2)
298
+
299
+const char *print_sockaddr_ex (const struct openvpn_sockaddr *addr,
300 300
 			       const char* separator,
301
+			       const unsigned int flags,
301 302
 			       struct gc_arena *gc);
302 303
 
303
-const char *print_sockaddr (const struct sockaddr_in *addr,
304
+
305
+const char *print_sockaddr (const struct openvpn_sockaddr *addr,
304 306
 			    struct gc_arena *gc);
305 307
 
308
+const char *print_link_socket_actual_ex (const struct link_socket_actual *act,
309
+					 const char* separator,
310
+					 const unsigned int flags,
311
+					 struct gc_arena *gc);
312
+
313
+const char *print_link_socket_actual (const struct link_socket_actual *act,
314
+				      struct gc_arena *gc);
315
+
316
+
306 317
 #define IA_EMPTY_IF_UNDEF (1<<0)
307 318
 #define IA_NET_ORDER      (1<<1)
308 319
 const char *print_in_addr_t (in_addr_t addr, unsigned int flags, struct gc_arena *gc);
... ...
@@ -311,7 +340,7 @@ const char *print_in_addr_t (in_addr_t addr, unsigned int flags, struct gc_arena
311 311
 #define SA_SET_IF_NONZERO (1<<1)
312 312
 void setenv_sockaddr (struct env_set *es,
313 313
 		      const char *name_prefix,
314
-		      const struct sockaddr_in *addr,
314
+		      const struct openvpn_sockaddr *addr,
315 315
 		      const bool flags);
316 316
 
317 317
 void setenv_in_addr_t (struct env_set *es,
... ...
@@ -319,19 +348,24 @@ void setenv_in_addr_t (struct env_set *es,
319 319
 		       in_addr_t addr,
320 320
 		       const bool flags);
321 321
 
322
+void setenv_link_socket_actual (struct env_set *es,
323
+				const char *name_prefix,
324
+				const struct link_socket_actual *act,
325
+				const bool flags);
326
+
322 327
 void bad_address_length (int actual, int expected);
323 328
 
324 329
 in_addr_t link_socket_current_remote (const struct link_socket_info *info);
325 330
 
326 331
 void link_socket_connection_initiated (const struct buffer *buf,
327 332
 				       struct link_socket_info *info,
328
-				       const struct sockaddr_in *addr,
333
+				       const struct link_socket_actual *addr,
329 334
 				       const char *common_name,
330 335
 				       struct env_set *es);
331 336
 
332 337
 void link_socket_bad_incoming_addr (struct buffer *buf,
333 338
 				    const struct link_socket_info *info,
334
-				    const struct sockaddr_in *from_addr);
339
+				    const struct link_socket_actual *from_addr);
335 340
 
336 341
 void link_socket_bad_outgoing_addr (void);
337 342
 
... ...
@@ -355,7 +389,7 @@ int openvpn_inet_aton (const char *dotted_quad, struct in_addr *addr);
355 355
 socket_descriptor_t create_socket_tcp (void);
356 356
 
357 357
 socket_descriptor_t socket_do_accept (socket_descriptor_t sd,
358
-				      struct sockaddr_in *remote,
358
+				      struct link_socket_actual *act,
359 359
 				      const bool nowait);
360 360
 
361 361
 /*
... ...
@@ -447,33 +481,39 @@ link_socket_connection_oriented (const struct link_socket *sock)
447 447
 }
448 448
 
449 449
 static inline bool
450
-addr_defined (const struct sockaddr_in *addr)
450
+addr_defined (const struct openvpn_sockaddr *addr)
451 451
 {
452
-  return addr->sin_addr.s_addr != 0;
452
+  return addr->sa.sin_addr.s_addr != 0;
453 453
 }
454 454
 
455 455
 static inline bool
456
-addr_match (const struct sockaddr_in *a1, const struct sockaddr_in *a2)
456
+link_socket_actual_defined (const struct link_socket_actual *act)
457 457
 {
458
-  return a1->sin_addr.s_addr == a2->sin_addr.s_addr;
458
+  return act && addr_defined (&act->dest);
459
+}
460
+
461
+static inline bool
462
+addr_match (const struct openvpn_sockaddr *a1, const struct openvpn_sockaddr *a2)
463
+{
464
+  return a1->sa.sin_addr.s_addr == a2->sa.sin_addr.s_addr;
459 465
 }
460 466
 
461 467
 static inline in_addr_t
462
-addr_host (const struct sockaddr_in *s)
468
+addr_host (const struct openvpn_sockaddr *s)
463 469
 {
464
-  return ntohl (s->sin_addr.s_addr);
470
+  return ntohl (s->sa.sin_addr.s_addr);
465 471
 }
466 472
 
467 473
 static inline bool
468
-addr_port_match (const struct sockaddr_in *a1, const struct sockaddr_in *a2)
474
+addr_port_match (const struct openvpn_sockaddr *a1, const struct openvpn_sockaddr *a2)
469 475
 {
470
-  return a1->sin_addr.s_addr == a2->sin_addr.s_addr
471
-    && a1->sin_port == a2->sin_port;
476
+  return a1->sa.sin_addr.s_addr == a2->sa.sin_addr.s_addr
477
+    && a1->sa.sin_port == a2->sa.sin_port;
472 478
 }
473 479
 
474 480
 static inline bool
475
-addr_match_proto (const struct sockaddr_in *a1,
476
-		  const struct sockaddr_in *a2,
481
+addr_match_proto (const struct openvpn_sockaddr *a1,
482
+		  const struct openvpn_sockaddr *a2,
477 483
 		  const int proto)
478 484
 {
479 485
   return link_socket_proto_connection_oriented (proto)
... ...
@@ -482,6 +522,12 @@ addr_match_proto (const struct sockaddr_in *a1,
482 482
 }
483 483
 
484 484
 static inline bool
485
+link_socket_actual_match (const struct link_socket_actual *a1, const struct link_socket_actual *a2)
486
+{
487
+  return addr_port_match (&a1->dest, &a2->dest);
488
+}
489
+
490
+static inline bool
485 491
 socket_connection_reset (const struct link_socket *sock, int status)
486 492
 {
487 493
   if (link_socket_connection_oriented (sock))
... ...
@@ -504,17 +550,17 @@ socket_connection_reset (const struct link_socket *sock, int status)
504 504
 static inline bool
505 505
 link_socket_verify_incoming_addr (struct buffer *buf,
506 506
 				  const struct link_socket_info *info,
507
-				  const struct sockaddr_in *from_addr)
507
+				  const struct link_socket_actual *from_addr)
508 508
 {
509 509
   if (buf->len > 0)
510 510
     {
511
-      if (from_addr->sin_family != AF_INET)
511
+      if (from_addr->dest.sa.sin_family != AF_INET)
512 512
 	return false;
513
-      if (!addr_defined (from_addr))
513
+      if (!link_socket_actual_defined (from_addr))
514 514
 	return false;
515 515
       if (info->remote_float || !addr_defined (&info->lsa->remote))
516 516
 	return true;
517
-      if (addr_match_proto (from_addr, &info->lsa->remote, info->proto))
517
+      if (addr_match_proto (&from_addr->dest, &info->lsa->remote, info->proto))
518 518
 	return true;
519 519
     }
520 520
   return false;
... ...
@@ -523,21 +569,18 @@ link_socket_verify_incoming_addr (struct buffer *buf,
523 523
 static inline void
524 524
 link_socket_get_outgoing_addr (struct buffer *buf,
525 525
 			      const struct link_socket_info *info,
526
-			      struct sockaddr_in *addr)
526
+			      struct link_socket_actual **act)
527 527
 {
528 528
   if (buf->len > 0)
529 529
     {
530 530
       struct link_socket_addr *lsa = info->lsa;
531
-      if (addr_defined (&lsa->actual))
532
-	{
533
-	  addr->sin_family = lsa->actual.sin_family;
534
-	  addr->sin_addr.s_addr = lsa->actual.sin_addr.s_addr;
535
-	  addr->sin_port = lsa->actual.sin_port;
536
-	}
531
+      if (link_socket_actual_defined (&lsa->actual))
532
+	*act = &lsa->actual;
537 533
       else
538 534
 	{
539 535
 	  link_socket_bad_outgoing_addr ();
540 536
 	  buf->len = 0;
537
+	  *act = NULL;
541 538
 	}
542 539
     }
543 540
 }
... ...
@@ -545,7 +588,7 @@ link_socket_get_outgoing_addr (struct buffer *buf,
545 545
 static inline void
546 546
 link_socket_set_outgoing_addr (const struct buffer *buf,
547 547
 			       struct link_socket_info *info,
548
-			       const struct sockaddr_in *addr,
548
+			       const struct link_socket_actual *act,
549 549
 			       const char *common_name,
550 550
 			       struct env_set *es)
551 551
 {
... ...
@@ -555,14 +598,14 @@ link_socket_set_outgoing_addr (const struct buffer *buf,
555 555
       if (
556 556
 	  /* new or changed address? */
557 557
 	  (!info->connection_established
558
-	   || !addr_match_proto (addr, &lsa->actual, info->proto))
558
+	   || !addr_match_proto (&act->dest, &lsa->actual.dest, info->proto))
559 559
 	  /* address undef or address == remote or --float */
560 560
 	  && (info->remote_float
561 561
 	      || !addr_defined (&lsa->remote)
562
-	      || addr_match_proto (addr, &lsa->remote, info->proto))
562
+	      || addr_match_proto (&act->dest, &lsa->remote, info->proto))
563 563
 	  )
564 564
 	{
565
-	  link_socket_connection_initiated (buf, info, addr, common_name, es);
565
+	  link_socket_connection_initiated (buf, info, act, common_name, es);
566 566
 	}
567 567
     }
568 568
 }
... ...
@@ -599,7 +642,7 @@ int link_socket_read_tcp (struct link_socket *sock,
599 599
 static inline int
600 600
 link_socket_read_udp_win32 (struct link_socket *sock,
601 601
 			    struct buffer *buf,
602
-			    struct sockaddr_in *from)
602
+			    struct link_socket_actual *from)
603 603
 {
604 604
   return socket_finalize (sock->sd, &sock->reads, buf, from);
605 605
 }
... ...
@@ -609,7 +652,7 @@ link_socket_read_udp_win32 (struct link_socket *sock,
609 609
 int link_socket_read_udp_posix (struct link_socket *sock,
610 610
 				struct buffer *buf,
611 611
 				int maxsize,
612
-				struct sockaddr_in *from);
612
+				struct link_socket_actual *from);
613 613
 
614 614
 #endif
615 615
 
... ...
@@ -618,7 +661,7 @@ static inline int
618 618
 link_socket_read (struct link_socket *sock,
619 619
 		  struct buffer *buf,
620 620
 		  int maxsize,
621
-		  struct sockaddr_in *from)
621
+		  struct link_socket_actual *from)
622 622
 {
623 623
   if (sock->info.proto == PROTO_UDPv4)
624 624
     {
... ...
@@ -634,7 +677,7 @@ link_socket_read (struct link_socket *sock,
634 634
   else if (sock->info.proto == PROTO_TCPv4_SERVER || sock->info.proto == PROTO_TCPv4_CLIENT)
635 635
     {
636 636
       /* from address was returned by accept */
637
-      *from = sock->info.lsa->actual;
637
+      from->dest.sa = sock->info.lsa->actual.dest.sa;
638 638
       return link_socket_read_tcp (sock, buf);
639 639
     }
640 640
   else
... ...
@@ -650,14 +693,14 @@ link_socket_read (struct link_socket *sock,
650 650
 
651 651
 int link_socket_write_tcp (struct link_socket *sock,
652 652
 			   struct buffer *buf,
653
-			   struct sockaddr_in *to);
653
+			   struct link_socket_actual *to);
654 654
 
655 655
 #ifdef WIN32
656 656
 
657 657
 static inline int
658 658
 link_socket_write_win32 (struct link_socket *sock,
659 659
 			 struct buffer *buf,
660
-			 struct sockaddr_in *to)
660
+			 struct link_socket_actual *to)
661 661
 {
662 662
   int err = 0;
663 663
   int status = 0;
... ...
@@ -682,17 +725,26 @@ link_socket_write_win32 (struct link_socket *sock,
682 682
 static inline int
683 683
 link_socket_write_udp_posix (struct link_socket *sock,
684 684
 			     struct buffer *buf,
685
-			     struct sockaddr_in *to)
685
+			     struct link_socket_actual *to)
686 686
 {
687
-  return sendto (sock->sd, BPTR (buf), BLEN (buf), 0,
688
-		 (struct sockaddr *) to,
689
-		 (socklen_t) sizeof (*to));
687
+#if ENABLE_IP_PKTINFO
688
+  int link_socket_write_udp_posix_sendmsg (struct link_socket *sock,
689
+					   struct buffer *buf,
690
+					   struct link_socket_actual *to);
691
+
692
+  if (sock->sockflags & SF_USE_IP_PKTINFO)
693
+    return link_socket_write_udp_posix_sendmsg (sock, buf, to);
694
+  else
695
+#endif
696
+    return sendto (sock->sd, BPTR (buf), BLEN (buf), 0,
697
+		   (struct sockaddr *) &to->dest.sa,
698
+		   (socklen_t) sizeof (to->dest.sa));
690 699
 }
691 700
 
692 701
 static inline int
693 702
 link_socket_write_tcp_posix (struct link_socket *sock,
694 703
 			     struct buffer *buf,
695
-			     struct sockaddr_in *to)
704
+			     struct link_socket_actual *to)
696 705
 {
697 706
   return send (sock->sd, BPTR (buf), BLEN (buf), MSG_NOSIGNAL);
698 707
 }
... ...
@@ -702,7 +754,7 @@ link_socket_write_tcp_posix (struct link_socket *sock,
702 702
 static inline int
703 703
 link_socket_write_udp (struct link_socket *sock,
704 704
 		       struct buffer *buf,
705
-		       struct sockaddr_in *to)
705
+		       struct link_socket_actual *to)
706 706
 {
707 707
 #ifdef WIN32
708 708
   return link_socket_write_win32 (sock, buf, to);
... ...
@@ -715,7 +767,7 @@ link_socket_write_udp (struct link_socket *sock,
715 715
 static inline int
716 716
 link_socket_write (struct link_socket *sock,
717 717
 		   struct buffer *buf,
718
-		   struct sockaddr_in *to)
718
+		   struct link_socket_actual *to)
719 719
 {
720 720
   if (sock->info.proto == PROTO_UDPv4)
721 721
     {
... ...
@@ -148,7 +148,8 @@ socks_handshake (socket_descriptor_t sd, volatile int *signal_received)
148 148
 }
149 149
 
150 150
 static bool
151
-recv_socks_reply (socket_descriptor_t sd, struct sockaddr_in *addr,
151
+recv_socks_reply (socket_descriptor_t sd,
152
+		  struct openvpn_sockaddr *addr,
152 153
 		  volatile int *signal_received)
153 154
 {
154 155
   char atyp = '\0';
... ...
@@ -159,9 +160,9 @@ recv_socks_reply (socket_descriptor_t sd, struct sockaddr_in *addr,
159 159
 
160 160
   if (addr != NULL)
161 161
     {
162
-      addr->sin_family = AF_INET;
163
-      addr->sin_addr.s_addr = htonl (INADDR_ANY);
164
-      addr->sin_port = htons (0);
162
+      addr->sa.sin_family = AF_INET;
163
+      addr->sa.sin_addr.s_addr = htonl (INADDR_ANY);
164
+      addr->sa.sin_port = htons (0);
165 165
     }
166 166
 
167 167
   while (len < 4 + alen + 2)
... ...
@@ -248,8 +249,8 @@ recv_socks_reply (socket_descriptor_t sd, struct sockaddr_in *addr,
248 248
   /* ATYP == 1 (IP V4 address) */
249 249
   if (atyp == '\x01' && addr != NULL)
250 250
     {
251
-      memcpy (&addr->sin_addr, buf + 4, sizeof (addr->sin_addr));
252
-      memcpy (&addr->sin_port, buf + 8, sizeof (addr->sin_port));
251
+      memcpy (&addr->sa.sin_addr, buf + 4, sizeof (addr->sa.sin_addr));
252
+      memcpy (&addr->sa.sin_port, buf + 8, sizeof (addr->sa.sin_port));
253 253
     }
254 254
 
255 255
 
... ...
@@ -310,7 +311,7 @@ void
310 310
 establish_socks_proxy_udpassoc (struct socks_proxy_info *p,
311 311
 			        socket_descriptor_t ctrl_sd, /* already open to proxy */
312 312
 				socket_descriptor_t udp_sd,
313
-				struct sockaddr_in *relay_addr,
313
+				struct openvpn_sockaddr *relay_addr,
314 314
 			        volatile int *signal_received)
315 315
 {
316 316
   if (!socks_handshake (ctrl_sd, signal_received))
... ...
@@ -352,7 +353,7 @@ establish_socks_proxy_udpassoc (struct socks_proxy_info *p,
352 352
  */
353 353
 void
354 354
 socks_process_incoming_udp (struct buffer *buf,
355
-			    struct sockaddr_in *from)
355
+			    struct link_socket_actual *from)
356 356
 {
357 357
   int atyp;
358 358
 
... ...
@@ -367,8 +368,8 @@ socks_process_incoming_udp (struct buffer *buf,
367 367
   if (atyp != 1)		/* ATYP == 1 (IP V4) */
368 368
     goto error;
369 369
 
370
-  buf_read (buf, &from->sin_addr, sizeof (from->sin_addr));
371
-  buf_read (buf, &from->sin_port, sizeof (from->sin_port));
370
+  buf_read (buf, &from->dest.sa.sin_addr, sizeof (from->dest.sa.sin_addr));
371
+  buf_read (buf, &from->dest.sa.sin_port, sizeof (from->dest.sa.sin_port));
372 372
 
373 373
   return;
374 374
 
... ...
@@ -385,7 +386,7 @@ socks_process_incoming_udp (struct buffer *buf,
385 385
  */
386 386
 int
387 387
 socks_process_outgoing_udp (struct buffer *buf,
388
-			    struct sockaddr_in *to)
388
+			    const struct link_socket_actual *to)
389 389
 {
390 390
   /* 
391 391
    * Get a 10 byte subset buffer prepended to buf --
... ...
@@ -400,8 +401,8 @@ socks_process_outgoing_udp (struct buffer *buf,
400 400
   buf_write_u16 (&head, 0);	/* RSV = 0 */
401 401
   buf_write_u8 (&head, 0);	/* FRAG = 0 */
402 402
   buf_write_u8 (&head, '\x01'); /* ATYP = 1 (IP V4) */
403
-  buf_write (&head, &to->sin_addr, sizeof (to->sin_addr));
404
-  buf_write (&head, &to->sin_port, sizeof (to->sin_port));
403
+  buf_write (&head, &to->dest.sa.sin_addr, sizeof (to->dest.sa.sin_addr));
404
+  buf_write (&head, &to->dest.sa.sin_port, sizeof (to->dest.sa.sin_port));
405 405
 
406 406
   return 10;
407 407
 }
... ...
@@ -34,6 +34,9 @@
34 34
 
35 35
 #include "buffer.h"
36 36
 
37
+struct openvpn_sockaddr;
38
+struct link_socket_actual;
39
+
37 40
 struct socks_proxy_info {
38 41
   bool defined;
39 42
   bool retry;
... ...
@@ -58,14 +61,14 @@ void establish_socks_proxy_passthru (struct socks_proxy_info *p,
58 58
 void establish_socks_proxy_udpassoc (struct socks_proxy_info *p,
59 59
 				     socket_descriptor_t ctrl_sd, /* already open to proxy */
60 60
 				     socket_descriptor_t udp_sd,
61
-				     struct sockaddr_in *relay_addr,
61
+				     struct openvpn_sockaddr *relay_addr,
62 62
 				     volatile int *signal_received);
63 63
 
64 64
 void socks_process_incoming_udp (struct buffer *buf,
65
-				struct sockaddr_in *from);
65
+				struct link_socket_actual *from);
66 66
 
67 67
 int socks_process_outgoing_udp (struct buffer *buf,
68
-				struct sockaddr_in *to);
68
+				const struct link_socket_actual *to);
69 69
 
70 70
 #endif
71 71
 #endif
... ...
@@ -374,7 +374,7 @@ extract_x509_field (const char *x509, const char *field_name, char *out, int siz
374 374
 static void
375 375
 setenv_untrusted (struct tls_session *session)
376 376
 {
377
-  setenv_sockaddr (session->opt->es, "untrusted", &session->untrusted_sockaddr, SA_IP_PORT);
377
+  setenv_link_socket_actual (session->opt->es, "untrusted", &session->untrusted_addr, SA_IP_PORT);
378 378
 }
379 379
 
380 380
 static void
... ...
@@ -1860,7 +1860,7 @@ static void
1860 1860
 write_control_auth (struct tls_session *session,
1861 1861
 		    struct key_state *ks,
1862 1862
 		    struct buffer *buf,
1863
-		    struct sockaddr_in *to_link_addr,
1863
+		    struct link_socket_actual **to_link_addr,
1864 1864
 		    int opcode,
1865 1865
 		    int max_ack,
1866 1866
 		    bool prepend_ack)
... ...
@@ -1868,7 +1868,7 @@ write_control_auth (struct tls_session *session,
1868 1868
   uint8_t *header;
1869 1869
   struct buffer null = clear_buf ();
1870 1870
 
1871
-  ASSERT (addr_defined (&ks->remote_addr));
1871
+  ASSERT (link_socket_actual_defined (&ks->remote_addr));
1872 1872
   ASSERT (reliable_ack_write
1873 1873
 	  (ks->rec_ack, buf, &ks->session_id_remote, max_ack, prepend_ack));
1874 1874
   ASSERT (session_id_write_prepend (&session->session_id, buf));
... ...
@@ -1880,7 +1880,7 @@ write_control_auth (struct tls_session *session,
1880 1880
       openvpn_encrypt (buf, null, &session->tls_auth, NULL);
1881 1881
       ASSERT (swap_hmac (buf, &session->tls_auth, false));
1882 1882
     }
1883
-  *to_link_addr = ks->remote_addr;
1883
+  *to_link_addr = &ks->remote_addr;
1884 1884
 }
1885 1885
 
1886 1886
 /*
... ...
@@ -1889,7 +1889,7 @@ write_control_auth (struct tls_session *session,
1889 1889
 static bool
1890 1890
 read_control_auth (struct buffer *buf,
1891 1891
 		   const struct crypto_options *co,
1892
-		   const struct sockaddr_in *from)
1892
+		   const struct link_socket_actual *from)
1893 1893
 {
1894 1894
   struct gc_arena gc = gc_new ();
1895 1895
 
... ...
@@ -1902,7 +1902,7 @@ read_control_auth (struct buffer *buf,
1902 1902
 	{
1903 1903
 	  msg (D_TLS_ERRORS,
1904 1904
 	       "TLS Error: cannot locate HMAC in incoming packet from %s",
1905
-	       print_sockaddr (from, &gc));
1905
+	       print_link_socket_actual (from, &gc));
1906 1906
 	  gc_free (&gc);
1907 1907
 	  return false;
1908 1908
 	}
... ...
@@ -1914,7 +1914,7 @@ read_control_auth (struct buffer *buf,
1914 1914
 	{
1915 1915
 	  msg (D_TLS_ERRORS,
1916 1916
 	       "TLS Error: incoming packet authentication failed from %s",
1917
-	       print_sockaddr (from, &gc));
1917
+	       print_link_socket_actual (from, &gc));
1918 1918
 	  gc_free (&gc);
1919 1919
 	  return false;
1920 1920
 	}
... ...
@@ -2803,7 +2803,7 @@ static bool
2803 2803
 tls_process (struct tls_multi *multi,
2804 2804
 	     struct tls_session *session,
2805 2805
 	     struct buffer *to_link,
2806
-	     struct sockaddr_in *to_link_addr,
2806
+	     struct link_socket_actual **to_link_addr,
2807 2807
 	     struct link_socket_info *to_link_socket_info,
2808 2808
 	     interval_t *wakeup)
2809 2809
 {
... ...
@@ -3197,7 +3197,7 @@ error:
3197 3197
 bool
3198 3198
 tls_multi_process (struct tls_multi *multi,
3199 3199
 		   struct buffer *to_link,
3200
-		   struct sockaddr_in *to_link_addr,
3200
+		   struct link_socket_actual **to_link_addr,
3201 3201
 		   struct link_socket_info *to_link_socket_info,
3202 3202
 		   interval_t *wakeup)
3203 3203
 {
... ...
@@ -3223,7 +3223,7 @@ tls_multi_process (struct tls_multi *multi,
3223 3223
 
3224 3224
       /* set initial remote address */
3225 3225
       if (i == TM_ACTIVE && ks->state == S_INITIAL &&
3226
-	  addr_defined (&to_link_socket_info->lsa->actual))
3226
+	  link_socket_actual_defined (&to_link_socket_info->lsa->actual))
3227 3227
 	ks->remote_addr = to_link_socket_info->lsa->actual;
3228 3228
 
3229 3229
       dmsg (D_TLS_DEBUG,
... ...
@@ -3232,17 +3232,30 @@ tls_multi_process (struct tls_multi *multi,
3232 3232
 	   state_name (ks->state),
3233 3233
 	   session_id_print (&session->session_id, &gc),
3234 3234
 	   session_id_print (&ks->session_id_remote, &gc),
3235
-	   print_sockaddr (&ks->remote_addr, &gc));
3235
+	   print_link_socket_actual (&ks->remote_addr, &gc));
3236 3236
 
3237
-      if (ks->state >= S_INITIAL && addr_defined (&ks->remote_addr))
3237
+      if (ks->state >= S_INITIAL && link_socket_actual_defined (&ks->remote_addr))
3238 3238
 	{
3239
+	  struct link_socket_actual *tla = NULL;
3240
+
3239 3241
 	  update_time ();
3240 3242
 
3241
-	  if (tls_process (multi, session, to_link, to_link_addr,
3243
+	  if (tls_process (multi, session, to_link, &tla,
3242 3244
 			   to_link_socket_info, wakeup))
3243 3245
 	    active = true;
3244 3246
 
3245 3247
 	  /*
3248
+	   * If tls_process produced an outgoing packet,
3249
+	   * return the link_socket_actual object (which
3250
+	   * contains the outgoing address).
3251
+	   */
3252
+	  if (tla)
3253
+	    {
3254
+	      multi->to_link_addr = *tla;
3255
+	      *to_link_addr = &multi->to_link_addr;
3256
+	    }
3257
+
3258
+	  /*
3246 3259
 	   * If tls_process hits an error:
3247 3260
 	   * (1) If the session has an unexpired lame duck key, preserve it.
3248 3261
 	   * (2) Reinitialize the session.
... ...
@@ -3361,7 +3374,7 @@ tls_multi_process (struct tls_multi *multi,
3361 3361
 
3362 3362
 bool
3363 3363
 tls_pre_decrypt (struct tls_multi *multi,
3364
-		 struct sockaddr_in *from,
3364
+		 const struct link_socket_actual *from,
3365 3365
 		 struct buffer *buf,
3366 3366
 		 struct crypto_options *opt)
3367 3367
 {
... ...
@@ -3403,7 +3416,7 @@ tls_pre_decrypt (struct tls_multi *multi,
3403 3403
 	      if (DECRYPT_KEY_ENABLED (multi, ks)
3404 3404
 		  && key_id == ks->key_id
3405 3405
 		  && ks->authenticated
3406
-		  && addr_port_match(from, &ks->remote_addr))
3406
+		  && link_socket_actual_match (from, &ks->remote_addr))
3407 3407
 		{
3408 3408
 		  /* return appropriate data channel decrypt key in opt */
3409 3409
 		  opt->key_ctx_bi = &ks->key;
... ...
@@ -3416,7 +3429,7 @@ tls_pre_decrypt (struct tls_multi *multi,
3416 3416
 		  ks->n_bytes += buf->len;
3417 3417
 		  dmsg (D_TLS_DEBUG,
3418 3418
 		       "TLS: data channel, key_id=%d, IP=%s",
3419
-		       key_id, print_sockaddr (from, &gc));
3419
+		       key_id, print_link_socket_actual (from, &gc));
3420 3420
 		  gc_free (&gc);
3421 3421
 		  return ret;
3422 3422
 		}
... ...
@@ -3429,14 +3442,14 @@ tls_pre_decrypt (struct tls_multi *multi,
3429 3429
 		       key_id,
3430 3430
 		       ks->key_id,
3431 3431
 		       ks->authenticated,
3432
-		       addr_port_match (from, &ks->remote_addr));
3432
+		       link_socket_actual_match (from, &ks->remote_addr));
3433 3433
 		}
3434 3434
 #endif
3435 3435
 	    }
3436 3436
 
3437 3437
 	  msg (D_TLS_ERRORS,
3438 3438
 	       "TLS Error: local/remote TLS keys are out of sync: %s [%d]",
3439
-	       print_sockaddr (from, &gc), key_id);
3439
+	       print_link_socket_actual (from, &gc), key_id);
3440 3440
 	  goto error;
3441 3441
 	}
3442 3442
       else			  /* control channel packet */
... ...
@@ -3450,7 +3463,7 @@ tls_pre_decrypt (struct tls_multi *multi,
3450 3450
 	    {
3451 3451
 	      msg (D_TLS_ERRORS,
3452 3452
 		   "TLS Error: unknown opcode received from %s op=%d",
3453
-		   print_sockaddr (from, &gc), op);
3453
+		   print_link_socket_actual (from, &gc), op);
3454 3454
 	      goto error;
3455 3455
 	    }
3456 3456
 
... ...
@@ -3465,7 +3478,7 @@ tls_pre_decrypt (struct tls_multi *multi,
3465 3465
 		{
3466 3466
 		  msg (D_TLS_ERRORS,
3467 3467
 		       "TLS Error: client->client or server->server connection attempted from %s",
3468
-		       print_sockaddr (from, &gc));
3468
+		       print_link_socket_actual (from, &gc));
3469 3469
 		  goto error;
3470 3470
 		}
3471 3471
 	    }
... ...
@@ -3474,7 +3487,7 @@ tls_pre_decrypt (struct tls_multi *multi,
3474 3474
 	   * Authenticate Packet
3475 3475
 	   */
3476 3476
 	  dmsg (D_TLS_DEBUG, "TLS: control channel, op=%s, IP=%s",
3477
-	       packet_opcode_name (op), print_sockaddr (from, &gc));
3477
+	       packet_opcode_name (op), print_link_socket_actual (from, &gc));
3478 3478
 
3479 3479
 	  /* get remote session-id */
3480 3480
 	  {
... ...
@@ -3484,7 +3497,7 @@ tls_pre_decrypt (struct tls_multi *multi,
3484 3484
 	      {
3485 3485
 		msg (D_TLS_ERRORS,
3486 3486
 		     "TLS Error: session-id not found in packet from %s",
3487
-		     print_sockaddr (from, &gc));
3487
+		     print_link_socket_actual (from, &gc));
3488 3488
 		goto error;
3489 3489
 	      }
3490 3490
 	  }
... ...
@@ -3501,9 +3514,9 @@ tls_pre_decrypt (struct tls_multi *multi,
3501 3501
 		   state_name (ks->state),
3502 3502
 		   session_id_print (&session->session_id, &gc),
3503 3503
 		   session_id_print (&sid, &gc),
3504
-		   print_sockaddr (from, &gc),
3504
+		   print_link_socket_actual (from, &gc),
3505 3505
 		   session_id_print (&ks->session_id_remote, &gc),
3506
-		   print_sockaddr (&ks->remote_addr, &gc));
3506
+		   print_link_socket_actual (&ks->remote_addr, &gc));
3507 3507
 
3508 3508
 	      if (session_id_equal (&ks->session_id_remote, &sid))
3509 3509
 		/* found a match */
... ...
@@ -3548,7 +3561,7 @@ tls_pre_decrypt (struct tls_multi *multi,
3548 3548
 		    {
3549 3549
 		      msg (D_TLS_ERRORS,
3550 3550
 			   "TLS Error: Cannot accept new session request from %s due to --single-session [1]",
3551
-			   print_sockaddr (from, &gc));
3551
+			   print_link_socket_actual (from, &gc));
3552 3552
 		      goto error;
3553 3553
 		    }
3554 3554
 
... ...
@@ -3564,13 +3577,13 @@ tls_pre_decrypt (struct tls_multi *multi,
3564 3564
 
3565 3565
 		  msg (D_TLS_DEBUG_LOW,
3566 3566
 		       "TLS: Initial packet from %s, sid=%s",
3567
-		       print_sockaddr (from, &gc),
3567
+		       print_link_socket_actual (from, &gc),
3568 3568
 		       session_id_print (&sid, &gc));
3569 3569
 
3570 3570
 		  do_burst = true;
3571 3571
 		  new_link = true;
3572 3572
 		  i = TM_ACTIVE;
3573
-		  session->untrusted_sockaddr = *from;
3573
+		  session->untrusted_addr = *from;
3574 3574
 		}
3575 3575
 	    }
3576 3576
 
... ...
@@ -3590,7 +3603,7 @@ tls_pre_decrypt (struct tls_multi *multi,
3590 3590
 		{
3591 3591
 		  msg (D_TLS_ERRORS,
3592 3592
 		       "TLS Error: Cannot accept new session request from %s due to --single-session [2]",
3593
-		       print_sockaddr (from, &gc));
3593
+		       print_link_socket_actual (from, &gc));
3594 3594
 		  goto error;
3595 3595
 		}
3596 3596
 	      
... ...
@@ -3613,11 +3626,11 @@ tls_pre_decrypt (struct tls_multi *multi,
3613 3613
 	       */
3614 3614
 	      msg (D_TLS_DEBUG_LOW,
3615 3615
 		   "TLS: new session incoming connection from %s",
3616
-		   print_sockaddr (from, &gc));
3616
+		   print_link_socket_actual (from, &gc));
3617 3617
 
3618 3618
 	      new_link = true;
3619 3619
 	      i = TM_UNTRUSTED;
3620
-	      session->untrusted_sockaddr = *from;
3620
+	      session->untrusted_addr = *from;
3621 3621
 	    }
3622 3622
 	  else
3623 3623
 	    {
... ...
@@ -3631,7 +3644,7 @@ tls_pre_decrypt (struct tls_multi *multi,
3631 3631
 		{
3632 3632
 		  msg (D_TLS_ERRORS,
3633 3633
 		       "TLS Error: Unroutable control packet received from %s (si=%d op=%s)",
3634
-		       print_sockaddr (from, &gc),
3634
+		       print_link_socket_actual (from, &gc),
3635 3635
 		       i,
3636 3636
 		       packet_opcode_name (op));
3637 3637
 		  goto error;
... ...
@@ -3640,10 +3653,10 @@ tls_pre_decrypt (struct tls_multi *multi,
3640 3640
 	      /*
3641 3641
 	       * Verify remote IP address
3642 3642
 	       */
3643
-	      if (!new_link && !addr_port_match (&ks->remote_addr, from))
3643
+	      if (!new_link && !link_socket_actual_match (&ks->remote_addr, from))
3644 3644
 		{
3645 3645
 		  msg (D_TLS_ERRORS, "TLS Error: Received control packet from unexpected IP addr: %s",
3646
-		      print_sockaddr (from, &gc));
3646
+		      print_link_socket_actual (from, &gc));
3647 3647
 		  goto error;
3648 3648
 		}
3649 3649
 
... ...
@@ -3705,11 +3718,11 @@ tls_pre_decrypt (struct tls_multi *multi,
3705 3705
 		ks->remote_addr = *from;
3706 3706
 		++multi->n_sessions;
3707 3707
 	      }
3708
-	    else if (!addr_port_match (&ks->remote_addr, from))
3708
+	    else if (!link_socket_actual_match (&ks->remote_addr, from))
3709 3709
 	      {
3710 3710
 		msg (D_TLS_ERRORS,
3711 3711
 		     "TLS Error: Existing session control channel packet from unknown IP address: %s",
3712
-		     print_sockaddr (from, &gc));
3712
+		     print_link_socket_actual (from, &gc));
3713 3713
 		goto error;
3714 3714
 	      }
3715 3715
 
... ...
@@ -3807,8 +3820,9 @@ tls_pre_decrypt (struct tls_multi *multi,
3807 3807
  */
3808 3808
 bool
3809 3809
 tls_pre_decrypt_lite (const struct tls_auth_standalone *tas,
3810
-		      const struct sockaddr_in *from,
3810
+		      const struct link_socket_actual *from,
3811 3811
 		      const struct buffer *buf)
3812
+
3812 3813
 {
3813 3814
   struct gc_arena gc = gc_new ();
3814 3815
   bool ret = false;
... ...
@@ -3835,7 +3849,7 @@ tls_pre_decrypt_lite (const struct tls_auth_standalone *tas,
3835 3835
 	   */
3836 3836
 	  dmsg (D_TLS_STATE_ERRORS,
3837 3837
 	       "TLS State Error: No TLS state for client %s, opcode=%d",
3838
-	       print_sockaddr (from, &gc),
3838
+	       print_link_socket_actual (from, &gc),
3839 3839
 	       op);
3840 3840
 	  goto error;
3841 3841
 	}
... ...
@@ -3845,7 +3859,7 @@ tls_pre_decrypt_lite (const struct tls_auth_standalone *tas,
3845 3845
 	  dmsg (D_TLS_STATE_ERRORS,
3846 3846
 	       "TLS State Error: Unknown key ID (%d) received from %s -- 0 was expected",
3847 3847
 	       key_id,
3848
-	       print_sockaddr (from, &gc));
3848
+	       print_link_socket_actual (from, &gc));
3849 3849
 	  goto error;
3850 3850
 	}
3851 3851
 
... ...
@@ -3854,7 +3868,7 @@ tls_pre_decrypt_lite (const struct tls_auth_standalone *tas,
3854 3854
 	  dmsg (D_TLS_STATE_ERRORS,
3855 3855
 	       "TLS State Error: Large packet (size %d) received from %s -- a packet no larger than %d bytes was expected",
3856 3856
 	       buf->len,
3857
-	       print_sockaddr (from, &gc),
3857
+	       print_link_socket_actual (from, &gc),
3858 3858
 	       EXPANDED_SIZE_DYNAMIC (&tas->frame));
3859 3859
 	  goto error;
3860 3860
 	}
... ...
@@ -344,8 +344,8 @@ struct key_state
344 344
   time_t must_die;		/* this object is destroyed at this time */
345 345
 
346 346
   int initial_opcode;		/* our initial P_ opcode */
347
-  struct session_id session_id_remote; /* peer's random session ID */
348
-  struct sockaddr_in remote_addr;      /* peer's IP addr */
347
+  struct session_id session_id_remote;   /* peer's random session ID */
348
+  struct link_socket_actual remote_addr; /* peer's IP addr */
349 349
   struct packet_id packet_id;	       /* for data channel, to prevent replay attacks */
350 350
 
351 351
   struct key_ctx_bi key;	       /* data channel keys for encrypt/decrypt/hmac */
... ...
@@ -488,7 +488,7 @@ struct tls_session
488 488
   bool verified;                /* true if peer certificate was verified against CA */
489 489
 
490 490
   /* not-yet-authenticated incoming client */
491
-  struct sockaddr_in untrusted_sockaddr;
491
+  struct link_socket_actual untrusted_addr;
492 492
 
493 493
   struct key_state key[KS_SIZE];
494 494
 };
... ...
@@ -535,6 +535,12 @@ struct tls_multi
535 535
   struct key_state *save_ks;	/* temporary pointer used between pre/post routines */
536 536
 
537 537
   /*
538
+   * Used to return outgoing address from
539
+   * tls_multi_process.
540
+   */
541
+  struct link_socket_actual to_link_addr;
542
+
543
+  /*
538 544
    * Number of sessions negotiated thus far.
539 545
    */
540 546
   int n_sessions;
... ...
@@ -590,19 +596,19 @@ void tls_multi_init_set_options(struct tls_multi* multi,
590 590
 
591 591
 bool tls_multi_process (struct tls_multi *multi,
592 592
 			struct buffer *to_link,
593
-			struct sockaddr_in *to_link_addr,
593
+			struct link_socket_actual **to_link_addr,
594 594
 			struct link_socket_info *to_link_socket_info,
595 595
 			interval_t *wakeup);
596 596
 
597 597
 void tls_multi_free (struct tls_multi *multi, bool clear);
598 598
 
599 599
 bool tls_pre_decrypt (struct tls_multi *multi,
600
-		      struct sockaddr_in *from,
600
+		      const struct link_socket_actual *from,
601 601
 		      struct buffer *buf,
602 602
 		      struct crypto_options *opt);
603 603
 
604 604
 bool tls_pre_decrypt_lite (const struct tls_auth_standalone *tas,
605
-			   const struct sockaddr_in *from,
605
+			   const struct link_socket_actual *from,
606 606
 			   const struct buffer *buf);
607 607
 
608 608
 void tls_pre_encrypt (struct tls_multi *multi,
... ...
@@ -310,6 +310,15 @@
310 310
 #endif
311 311
 
312 312
 /*
313
+ * Does this platform support linux-style IP_PKTINFO?
314
+ */
315
+#if defined(ENABLE_MULTIHOME) && defined(HAVE_IN_PKTINFO) && defined(IP_PKTINFO) && defined(HAVE_MSGHDR) && defined(HAVE_CMSGHDR) && defined(HAVE_IOVEC) && defined(CMSG_FIRSTHDR) && defined(CMSG_NXTHDR) && defined(HAVE_RECVMSG) && defined(HAVE_SENDMSG)
316
+#define ENABLE_IP_PKTINFO 1
317
+#else
318
+#define ENABLE_IP_PKTINFO 0
319
+#endif
320
+
321
+/*
313 322
  * Disable ESEC
314 323
  */
315 324
 #if 0