Use two sockets, one for input and one for output bound to the outgoing IP.
authorHenning Rogge <hrogge@googlemail.com>
Mon, 30 Nov 2009 16:09:25 +0000 (17:09 +0100)
committerHenning Rogge <hrogge@googlemail.com>
Mon, 30 Nov 2009 16:09:25 +0000 (17:09 +0100)
Signed-off-by: Alina Friedrichsen <x-alina@gmx.net>
src/bsd/net.c
src/interfaces.h
src/linux/net.c
src/main.c
src/net_olsr.c
src/net_os.h
src/unix/ifnet.c
src/win32/ifnet.c
src/win32/net.c

index b512e29..53a8457 100644 (file)
@@ -329,7 +329,7 @@ gethemusocket(struct sockaddr_in *pin)
 }
 
 int
-getsocket(int bufspace, char *int_name __attribute__ ((unused)))
+getsocket(int bufspace, struct interface *ifp __attribute__ ((unused)))
 {
   struct sockaddr_in sin;
   int on;
@@ -366,20 +366,26 @@ getsocket(int bufspace, char *int_name __attribute__ ((unused)))
     return -1;
   }
 
-  for (on = bufspace;; on -= 1024) {
-    if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&on, sizeof(on)) == 0)
-      break;
-    if (on <= 8 * 1024) {
-      perror("setsockopt");
-      syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m");
-      break;
+  if(bufspace > 0) {
+    for (on = bufspace;; on -= 1024) {
+      if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&on, sizeof(on)) == 0)
+        break;
+      if (on <= 8 * 1024) {
+        perror("setsockopt");
+        syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m");
+        break;
+      }
     }
   }
 
   memset(&sin, 0, sizeof(sin));
   sin.sin_family = AF_INET;
   sin.sin_port = htons(olsr_cnf->olsrport);
-  sin.sin_addr.s_addr = INADDR_ANY;
+
+  if(bufspace <= 0) {
+    sin.sin_addr.s_addr = ifp->int_addr.sin_addr.s_addr;
+  }
+
   if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
     perror("bind");
     syslog(LOG_ERR, "bind: %m");
@@ -399,7 +405,7 @@ getsocket(int bufspace, char *int_name __attribute__ ((unused)))
 }
 
 int
-getsocket6(int bufspace, char *int_name __attribute__ ((unused)))
+getsocket6(int bufspace, struct interface *ifp __attribute__ ((unused)))
 {
   struct sockaddr_in6 sin;
   int on;
@@ -411,13 +417,15 @@ getsocket6(int bufspace, char *int_name __attribute__ ((unused)))
     return -1;
   }
 
-  for (on = bufspace;; on -= 1024) {
-    if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&on, sizeof(on)) == 0)
-      break;
-    if (on <= 8 * 1024) {
-      perror("setsockopt");
-      syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m");
-      break;
+  if(bufspace > 0) {
+    for (on = bufspace;; on -= 1024) {
+      if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&on, sizeof(on)) == 0)
+        break;
+      if (on <= 8 * 1024) {
+        perror("setsockopt");
+        syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m");
+        break;
+      }
     }
   }
 
@@ -449,6 +457,11 @@ getsocket6(int bufspace, char *int_name __attribute__ ((unused)))
   memset(&sin, 0, sizeof(sin));
   sin.sin6_family = AF_INET6;
   sin.sin6_port = htons(olsr_cnf->olsrport);
+
+  if(bufspace <= 0) {
+    memcpy(&sin.sin6_addr, &ifp->int6_addr.sin6_addr, sizeof(struct in6_addr));
+  }
+
   if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
     perror("bind");
     syslog(LOG_ERR, "bind: %m");
index b0e638d..48863f5 100644 (file)
@@ -135,6 +135,7 @@ struct interface {
   int is_hcif;                         /* Is this a emulated host-client if? */
 
   int olsr_socket;                     /* The broadcast socket for this interface */
+  int send_socket;                     /* The send socket for this interface */
 
   int int_metric;                      /* metric of interface */
   int int_mtu;                         /* MTU of interface */
index 0a39241..ff33db0 100644 (file)
@@ -379,7 +379,7 @@ gethemusocket(struct sockaddr_in *pin)
  *@return the FD of the socket or -1 on error.
  */
 int
-getsocket(int bufspace, char *int_name)
+getsocket(int bufspace, struct interface *ifp)
 {
   struct sockaddr_in sin;
   int on;
@@ -406,13 +406,15 @@ getsocket(int bufspace, char *int_name)
     return -1;
   }
 #ifdef SO_RCVBUF
-  for (on = bufspace;; on -= 1024) {
-    if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &on, sizeof(on)) == 0)
-      break;
-    if (on <= 8 * 1024) {
-      perror("setsockopt");
-      syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m");
-      break;
+  if(bufspace > 0) {
+    for (on = bufspace;; on -= 1024) {
+      if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &on, sizeof(on)) == 0)
+        break;
+      if (on <= 8 * 1024) {
+        perror("setsockopt");
+        syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m");
+        break;
+      }
     }
   }
 #endif
@@ -422,7 +424,7 @@ getsocket(int bufspace, char *int_name)
    */
 
   /* Bind to device */
-  if (bind_socket_to_device(sock, int_name) < 0) {
+  if (bind_socket_to_device(sock, ifp->int_name) < 0) {
     fprintf(stderr, "Could not bind socket to device... exiting!\n\n");
     syslog(LOG_ERR, "Could not bind socket to device... exiting!\n\n");
     close(sock);
@@ -432,7 +434,11 @@ getsocket(int bufspace, char *int_name)
   memset(&sin, 0, sizeof(sin));
   sin.sin_family = AF_INET;
   sin.sin_port = htons(olsr_cnf->olsrport);
-  sin.sin_addr.s_addr = INADDR_ANY;
+
+  if(bufspace <= 0) {
+    sin.sin_addr.s_addr = ifp->int_addr.sin_addr.s_addr;
+  }
+
   if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
     perror("bind");
     syslog(LOG_ERR, "bind: %m");
@@ -457,7 +463,7 @@ getsocket(int bufspace, char *int_name)
  *@return the FD of the socket or -1 on error.
  */
 int
-getsocket6(int bufspace, char *int_name)
+getsocket6(int bufspace, struct interface *ifp)
 {
   struct sockaddr_in6 sin;
   int on;
@@ -488,13 +494,15 @@ getsocket6(int bufspace, char *int_name)
   //#endif
 
 #ifdef SO_RCVBUF
-  for (on = bufspace;; on -= 1024) {
-    if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &on, sizeof(on)) == 0)
-      break;
-    if (on <= 8 * 1024) {
-      perror("setsockopt");
-      syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m");
-      break;
+  if(bufspace > 0) {
+    for (on = bufspace;; on -= 1024) {
+      if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &on, sizeof(on)) == 0)
+        break;
+      if (on <= 8 * 1024) {
+        perror("setsockopt");
+        syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m");
+        break;
+      }
     }
   }
 #endif
@@ -510,7 +518,7 @@ getsocket6(int bufspace, char *int_name)
    */
 
   /* Bind to device */
-  if (bind_socket_to_device(sock, int_name) < 0) {
+  if (bind_socket_to_device(sock, ifp->int_name) < 0) {
     fprintf(stderr, "Could not bind socket to device... exiting!\n\n");
     syslog(LOG_ERR, "Could not bind socket to device... exiting!\n\n");
     close(sock);
@@ -520,7 +528,11 @@ getsocket6(int bufspace, char *int_name)
   memset(&sin, 0, sizeof(sin));
   sin.sin6_family = AF_INET6;
   sin.sin6_port = htons(olsr_cnf->olsrport);
-  //(addrsock6.sin6_addr).s_addr = IN6ADDR_ANY_INIT;
+
+  if(bufspace <= 0) {
+    memcpy(&sin.sin6_addr, &ifp->int6_addr.sin6_addr, sizeof(struct in6_addr));
+  }
+
   if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
     perror("bind");
     syslog(LOG_ERR, "bind: %m");
index 245f43b..de78b02 100644 (file)
@@ -557,8 +557,10 @@ static void olsr_shutdown(int signo __attribute__ ((unused)))
   }
 
   /* OLSR sockets */
-  for (ifn = ifnet; ifn; ifn = ifn->int_next)
+  for (ifn = ifnet; ifn; ifn = ifn->int_next) {
     close(ifn->olsr_socket);
+    close(ifn->send_socket);
+  }
 
   /* Closing plug-ins */
   olsr_close_plugins();
index ed33107..c7cd5b1 100644 (file)
@@ -389,7 +389,7 @@ net_output(struct interface *ifp)
 
   if (olsr_cnf->ip_version == AF_INET) {
     /* IP version 4 */
-    if (olsr_sendto(ifp->olsr_socket, ifp->netbuf.buff, ifp->netbuf.pending, MSG_DONTROUTE, (struct sockaddr *)sin, sizeof(*sin)) <
+    if (olsr_sendto(ifp->send_socket, ifp->netbuf.buff, ifp->netbuf.pending, MSG_DONTROUTE, (struct sockaddr *)sin, sizeof(*sin)) <
         0) {
       perror("sendto(v4)");
       olsr_syslog(OLSR_LOG_ERR, "OLSR: sendto IPv4 %m");
@@ -397,7 +397,7 @@ net_output(struct interface *ifp)
     }
   } else {
     /* IP version 6 */
-    if (olsr_sendto(ifp->olsr_socket, ifp->netbuf.buff, ifp->netbuf.pending, MSG_DONTROUTE, (struct sockaddr *)sin6, sizeof(*sin6))
+    if (olsr_sendto(ifp->send_socket, ifp->netbuf.buff, ifp->netbuf.pending, MSG_DONTROUTE, (struct sockaddr *)sin6, sizeof(*sin6))
         < 0) {
       struct ipaddr_str buf;
       perror("sendto(v6)");
index d930c3f..49f3bf4 100644 (file)
@@ -75,9 +75,9 @@ int enable_ip_forwarding(int);
 
 int gethemusocket(struct sockaddr_in *);
 
-int getsocket(int, char *);
+int getsocket(int, struct interface *);
 
-int getsocket6(int, char *);
+int getsocket6(int, struct interface *);
 
 int get_ipv6_address(char *, struct sockaddr_in6 *, int);
 
index 634a03c..e1f3946 100644 (file)
@@ -824,7 +824,8 @@ chk_if_up(struct olsr_if *iface, int debuglvl __attribute__ ((unused)))
      *on what interface the message is transmitted
      */
 
-    ifp->olsr_socket = getsocket(BUFSPACE, ifp->int_name);
+    ifp->olsr_socket = getsocket(BUFSPACE, ifp);
+    ifp->send_socket = getsocket(0, ifp);
 
     if (ifp->olsr_socket < 0) {
       fprintf(stderr, "Could not initialize socket... exiting!\n\n");
@@ -843,7 +844,8 @@ chk_if_up(struct olsr_if *iface, int debuglvl __attribute__ ((unused)))
      *on what interface the message is transmitted
      */
 
-    ifp->olsr_socket = getsocket6(BUFSPACE, ifp->int_name);
+    ifp->olsr_socket = getsocket6(BUFSPACE, ifp);
+    ifp->send_socket = getsocket6(0, ifp);
 
     join_mcast(ifp, ifp->olsr_socket);
 
index b581116..b635103 100644 (file)
@@ -928,6 +928,7 @@ chk_if_up(struct olsr_if *IntConf, int DebugLevel __attribute__ ((unused)))
   OLSR_PRINTF(3, "\tKernel index: %08x\n", New->if_index);
 
   New->olsr_socket = getsocket(BUFSPACE, New->int_name);
+  New->send_socket = getsocket(0, New->int_name);
 
   if (New->olsr_socket < 0) {
     fprintf(stderr, "Could not initialize socket... exiting!\n\n");
index 5bc5689..2f3061d 100644 (file)
@@ -97,7 +97,7 @@ gethemusocket(struct sockaddr_in *pin)
 }
 
 int
-getsocket(int BuffSize, char *Int __attribute__ ((unused)))
+getsocket(int BuffSize, struct interface *ifp __attribute__ ((unused)))
 {
   struct sockaddr_in Addr;
   int On = 1;
@@ -133,7 +133,11 @@ getsocket(int BuffSize, char *Int __attribute__ ((unused)))
   memset(&Addr, 0, sizeof(Addr));
   Addr.sin_family = AF_INET;
   Addr.sin_port = htons(olsr_cnf->olsrport);
-  Addr.sin_addr.s_addr = INADDR_ANY;
+
+  if(bufspace <= 0) {
+    sin.sin_addr.s_addr = ifp->int_addr.sin_addr.s_addr;
+  }
+
   if (bind(Sock, (struct sockaddr *)&Addr, sizeof(Addr)) < 0) {
     WinSockPError("getsocket/bind()");
     closesocket(Sock);
@@ -150,7 +154,7 @@ getsocket(int BuffSize, char *Int __attribute__ ((unused)))
 }
 
 int
-getsocket6(int BuffSize, char *Int __attribute__ ((unused)))
+getsocket6(int BuffSize, struct interface *ifp __attribute__ ((unused)))
 {
   struct sockaddr_in6 Addr6;
   int On = 1;
@@ -185,7 +189,11 @@ getsocket6(int BuffSize, char *Int __attribute__ ((unused)))
   memset(&Addr6, 0, sizeof(Addr6));
   Addr6.sin6_family = AF_INET6;
   Addr6.sin6_port = htons(olsr_cnf->olsrport);
-  //Addr6.sin6_addr.s_addr = IN6ADDR_ANY_INIT;
+
+  if(bufspace <= 0) {
+    memcpy(&Addr6.sin6_addr, &ifp->int6_addr.sin6_addr, sizeof(struct in6_addr));
+  }
+
   if (bind(Sock, (struct sockaddr *)&Addr6, sizeof(Addr6)) < 0) {
     WinSockPError("getsocket6/bind()");
     closesocket(Sock);