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:37:30 +0000 (17:37 +0100)
committerHenning Rogge <hrogge@googlemail.com>
Mon, 30 Nov 2009 16:37:30 +0000 (17:37 +0100)
Signed-off-by: Alina Friedrichsen <x-alina@gmx.net>
src/bsd/net.c
src/interfaces.c
src/interfaces.h
src/linux/net.c
src/net_olsr.c
src/net_os.h
src/unix/ifnet.c
src/win32/ifnet.c
src/win32/net.c

index 85fdad1..1c0158f 100644 (file)
@@ -294,7 +294,7 @@ restore_settings(int version)
 
 
 int
-getsocket(int bufspace, char *int_name __attribute__ ((unused)))
+getsocket(int bufspace, struct interface *ifp __attribute__ ((unused)))
 {
   struct sockaddr_in sin4;
   int on;
@@ -329,21 +329,29 @@ getsocket(int bufspace, char *int_name __attribute__ ((unused)))
     olsr_exit(EXIT_FAILURE);
   }
 
-  for (on = bufspace;; on -= 1024) {
-    if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&on, sizeof(on)) == 0) {
-      OLSR_DEBUG(LOG_NETWORKING, "Set socket buffer space to %d\n", on);
-      break;
-    }
-    if (on <= 8 * 1024) {
-      OLSR_WARN(LOG_NETWORKING, "Could not set a socket buffer space for OLSR PDUs (%s)\n", strerror(errno));
-      break;
+  if (bufspace > 0) {
+    for (on = bufspace;; on -= 1024) {
+      if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&on, sizeof(on)) == 0) {
+        OLSR_DEBUG(LOG_NETWORKING, "Set socket buffer space to %d\n", on);
+        break;
+      }
+      if (on <= 8 * 1024) {
+        OLSR_WARN(LOG_NETWORKING, "Could not set a socket buffer space for OLSR PDUs (%s)\n", strerror(errno));
+        break;
+      }
     }
   }
-
   memset(&sin4, 0, sizeof(sin4));
   sin4.sin_family = AF_INET;
   sin4.sin_port = htons(OLSRPORT);
-  sin4.sin_addr.s_addr = INADDR_ANY;
+
+  if(bufspace <= 0) {
+    sin.sin_addr.s_addr = ifp->int_addr.sin_addr.s_addr;
+  }
+  else {
+    sin4.sin_addr.s_addr = INADDR_ANY;
+  }
+
   if (bind(sock, (struct sockaddr *)&sin4, sizeof(sin4)) < 0) {
     OLSR_ERROR(LOG_NETWORKING, "Coult not bind socket for OLSR PDUs to port (%s)\n", strerror(errno));
     close(sock);
@@ -355,7 +363,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 sin6;
   int on;
@@ -366,14 +374,16 @@ getsocket6(int bufspace, char *int_name __attribute__ ((unused)))
     olsr_exit(EXIT_FAILURE);
   }
 
-  for (on = bufspace;; on -= 1024) {
-    if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&on, sizeof(on)) == 0) {
-      OLSR_DEBUG(LOG_NETWORKING, "Set socket buffer space to %d\n", on);
-      break;
-    }
-    if (on <= 8 * 1024) {
-      OLSR_WARN(LOG_NETWORKING, "Could not set a socket buffer space for OLSR PDUs (%s)\n", strerror(errno));
-      break;
+  if (bufspace > 0) {
+    for (on = bufspace;; on -= 1024) {
+      if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&on, sizeof(on)) == 0) {
+        OLSR_DEBUG(LOG_NETWORKING, "Set socket buffer space to %d\n", on);
+        break;
+      }
+      if (on <= 8 * 1024) {
+        OLSR_WARN(LOG_NETWORKING, "Could not set a socket buffer space for OLSR PDUs (%s)\n", strerror(errno));
+        break;
+      }
     }
   }
 
@@ -405,6 +415,11 @@ getsocket6(int bufspace, char *int_name __attribute__ ((unused)))
   memset(&sin6, 0, sizeof(sin6));
   sin6.sin6_family = AF_INET6;
   sin6.sin6_port = htons(OLSRPORT);
+
+  if(bufspace <= 0) {
+    memcpy(&sin.sin6_addr, &ifp->int6_addr.sin6_addr, sizeof(struct in6_addr));
+  }
+
   if (bind(sock, (struct sockaddr *)&sin6, sizeof(sin6)) < 0) {
     OLSR_ERROR(LOG_NETWORKING, "Coult not bind socket for OLSR PDUs to port (%s)\n", strerror(errno));
     close(sock);
index 2c0fe72..a9dc60f 100644 (file)
@@ -296,6 +296,7 @@ remove_interface(struct interface **pinterf)
   /* Close olsr socket */
   remove_olsr_socket(ifp->olsr_socket, &olsr_input, NULL);
   CLOSESOCKET(ifp->olsr_socket);
+  CLOSESOCKET(ifp->send_socket);
   ifp->olsr_socket = -1;
 
 //  free(ifp->int_name);
index c88b40f..a3d8512 100644 (file)
@@ -136,6 +136,7 @@ struct interface {
   /* IP independent */
   union olsr_ip_addr ip_addr;
   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 */
   int int_flags;                       /* see below */
index db9143d..10a0aa4 100644 (file)
@@ -348,7 +348,7 @@ restore_settings(int version)
  *@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 sin4;
   int on;
@@ -373,14 +373,16 @@ getsocket(int bufspace, char *int_name)
     olsr_exit(EXIT_FAILURE);
   }
 #ifdef SO_RCVBUF
-  for (on = bufspace;; on -= 1024) {
-    if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &on, sizeof(on)) == 0) {
-      OLSR_DEBUG(LOG_NETWORKING, "Set socket buffer space to %d\n", on);
-      break;
-    }
-    if (on <= 8 * 1024) {
-      OLSR_WARN(LOG_NETWORKING, "Could not set a socket buffer space for OLSR PDUs (%s)\n", strerror(errno));
-      break;
+  if(bufspace > 0) {
+    for (on = bufspace;; on -= 1024) {
+      if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &on, sizeof(on)) == 0) {
+        OLSR_DEBUG(LOG_NETWORKING, "Set socket buffer space to %d\n", on);
+        break;
+      }
+      if (on <= 8 * 1024) {
+        OLSR_WARN(LOG_NETWORKING, "Could not set a socket buffer space for OLSR PDUs (%s)\n", strerror(errno));
+        break;
+      }
     }
   }
 #endif
@@ -390,7 +392,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) {
     OLSR_ERROR(LOG_NETWORKING, "Could not bind socket for OLSR PDUs to device (%s)\n", strerror(errno));
     close(sock);
     olsr_exit(EXIT_FAILURE);
@@ -399,7 +401,13 @@ getsocket(int bufspace, char *int_name)
   memset(&sin4, 0, sizeof(sin4));
   sin4.sin_family = AF_INET;
   sin4.sin_port = htons(olsr_cnf->olsr_port);
-  assert(sin4.sin_addr.s_addr == INADDR_ANY);
+
+  if(bufspace <= 0) {
+    sin4.sin_addr.s_addr = ifp->int_addr.sin_addr.s_addr;
+  }
+  else {
+    assert(sin4.sin_addr.s_addr == INADDR_ANY);
+  }
   if (bind(sock, (struct sockaddr *)&sin4, sizeof(sin4)) < 0) {
     OLSR_ERROR(LOG_NETWORKING, "Coult not bind socket for OLSR PDUs to port (%s)\n", strerror(errno));
     close(sock);
@@ -417,7 +425,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 sin6;
   int on;
@@ -447,14 +455,16 @@ 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) {
-      OLSR_DEBUG(LOG_NETWORKING, "Set socket buffer space to %d\n", on);
-      break;
-    }
-    if (on <= 8 * 1024) {
-      OLSR_WARN(LOG_NETWORKING, "Could not set a socket buffer space for OLSR PDUs (%s)\n", strerror(errno));
-      break;
+  if(bufspace > 0) {
+    for (on = bufspace;; on -= 1024) {
+      if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &on, sizeof(on)) == 0) {
+        OLSR_DEBUG(LOG_NETWORKING, "Set socket buffer space to %d\n", on);
+        break;
+      }
+      if (on <= 8 * 1024) {
+        OLSR_WARN(LOG_NETWORKING, "Could not set a socket buffer space for OLSR PDUs (%s)\n", strerror(errno));
+        break;
+      }
     }
   }
 #endif
@@ -482,8 +492,8 @@ getsocket6(int bufspace, char *int_name)
    */
 
   /* Bind to device */
-  if (bind_socket_to_device(sock, int_name) < 0) {
-    OLSR_ERROR(LOG_NETWORKING, "Cannot bind socket for OLSR PDUs to interface %s (%s)\n", int_name, strerror(errno));
+  if (bind_socket_to_device(sock, ifp->int_name) < 0) {
+    OLSR_ERROR(LOG_NETWORKING, "Cannot bind socket for OLSR PDUs to interface %s (%s)\n", ifp->int_name, strerror(errno));
     close(sock);
     olsr_exit(EXIT_FAILURE);
   }
@@ -491,7 +501,13 @@ getsocket6(int bufspace, char *int_name)
   memset(&sin6, 0, sizeof(sin6));
   sin6.sin6_family = AF_INET6;
   sin6.sin6_port = htons(olsr_cnf->olsr_port);
-  assert(0 == memcmp(&sin6.sin6_addr, &in6addr_any, sizeof(sin6.sin6_addr)));   /* == IN6ADDR_ANY_INIT */
+
+  if(bufspace <= 0) {
+    memcpy(&sin6.sin6_addr, &ifp->int6_addr.sin6_addr, sizeof(struct in6_addr));
+  }
+  else {
+    assert(0 == memcmp(&sin6.sin6_addr, &in6addr_any, sizeof(sin6.sin6_addr)));   /* == IN6ADDR_ANY_INIT */
+  }
   if (bind(sock, (struct sockaddr *)&sin6, sizeof(sin6)) < 0) {
     OLSR_ERROR(LOG_NETWORKING, "Cannot bind socket for OLSR PDUs (%s)\n", strerror(errno));
     close(sock);
index ad297cc..276f970 100644 (file)
@@ -361,7 +361,7 @@ net_output(struct interface *ifp)
     tmp_ptf->function(ifp->netbuf.buff, &ifp->netbuf.pending);
   }
 
-  if (olsr_sendto(ifp->olsr_socket, ifp->netbuf.buff, ifp->netbuf.pending, MSG_DONTROUTE, &dstaddr.sin, dstaddr_size) < 0) {
+  if (olsr_sendto(ifp->send_socket, ifp->netbuf.buff, ifp->netbuf.pending, MSG_DONTROUTE, &dstaddr.sin, dstaddr_size) < 0) {
 #if !defined REMOVE_LOG_WARN
     const int save_errno = errno;
 #endif
index c669714..de08efb 100644 (file)
@@ -60,46 +60,33 @@ ssize_t olsr_sendto(int, const void *, size_t, int, const struct sockaddr *, soc
 
 ssize_t olsr_recvfrom(int, void *, size_t, int, struct sockaddr *, socklen_t *);
 
-int
-  olsr_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
+int olsr_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
 
-int
-  convert_ip_to_mac(union olsr_ip_addr *, struct sockaddr *, char *);
+int convert_ip_to_mac(union olsr_ip_addr *, struct sockaddr *, char *);
 
-int
-  disable_redirects(const char *, struct interface *, int);
+int disable_redirects(const char *, struct interface *, int);
 
-int
-  disable_redirects_global(int);
+int disable_redirects_global(int);
 
-int
-  deactivate_spoof(const char *, struct interface *, int);
+int deactivate_spoof(const char *, struct interface *, int);
 
-int
-  restore_settings(int);
+int restore_settings(int);
 
-int
-  enable_ip_forwarding(int);
+int enable_ip_forwarding(int);
 
-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);
+int get_ipv6_address(char *, struct sockaddr_in6 *, int);
 
-int
-  calculate_if_metric(char *);
+int calculate_if_metric(char *);
 
-int
-  check_wireless_interface(char *);
+int check_wireless_interface(char *);
 
 bool is_if_link_up(char *);
 
-int
-  join_mcast(struct interface *, int);
+int join_mcast(struct interface *, int);
 
 #endif
 
index 62c671a..25c15c8 100644 (file)
@@ -535,7 +535,9 @@ chk_if_up(struct olsr_if_config *iface)
      * the socket to it. This to ensure that we can control
      * 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) {
       OLSR_ERROR(LOG_INTERFACE, "Could not initialize socket... exiting!\n\n");
       olsr_exit(EXIT_FAILURE);
@@ -548,7 +550,9 @@ chk_if_up(struct olsr_if_config *iface)
      * the socket to it. This to ensure that we can control
      * 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 26a8f66..0a1bbf3 100644 (file)
@@ -706,6 +706,7 @@ chk_if_up(struct olsr_if_config *IntConf)
   OLSR_INFO(LOG_NETWORKING, "\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) {
     OLSR_ERROR(LOG_NETWORKING, "Could not initialize socket... exiting!\n\n");
index 305e2f6..05bc9a8 100644 (file)
@@ -74,7 +74,7 @@ int disable_ip_forwarding(int Ver);
 
 
 int
-getsocket(int BuffSize, char *Int __attribute__ ((unused)))
+getsocket(int BuffSize, struct interface *ifp __attribute__ ((unused)))
 {
   struct sockaddr_in Addr;
   int On = 1;
@@ -109,8 +109,15 @@ getsocket(int BuffSize, char *Int __attribute__ ((unused)))
 
   memset(&Addr, 0, sizeof(Addr));
   Addr.sin_family = AF_INET;
-  Addr.sin_port = htons(OLSRPORT);
-  Addr.sin_addr.s_addr = INADDR_ANY;
+  Addr.sin_port = htons(olsr_cnf->olsrport);
+
+  if(bufspace <= 0) {
+    Addr.sin_addr.s_addr = ifp->int_addr.sin_addr.s_addr;
+  }
+  else {
+    Addr.sin_addr.s_addr = INADDR_ANY;
+  }
+
   if (bind(Sock, (struct sockaddr *)&Addr, sizeof(Addr)) < 0) {
     OLSR_ERROR(LOG_NETWORKING, "Could not bind socket for OLSR PDUs to device (%s)\n", strerror(errno));
     CLOSESOCKET(Sock);
@@ -127,7 +134,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;
@@ -161,8 +168,12 @@ getsocket6(int BuffSize, char *Int __attribute__ ((unused)))
 
   memset(&Addr6, 0, sizeof(Addr6));
   Addr6.sin6_family = AF_INET6;
-  Addr6.sin6_port = htons(OLSRPORT);
-  //Addr6.sin6_addr.s_addr = IN6ADDR_ANY_INIT;
+  Addr6.sin6_port = htons(olsr_cnf->olsrport);
+
+  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) {
     OLSR_ERROR(LOG_NETWORKING, "Could not bind socket for OLSR PDUs to device (%s)\n", strerror(errno));
     CLOSESOCKET(Sock);