Просмотр исходного кода

* Fixed open_telnet_raw() to NOT re-dns (with blocking calls) the specified host if it
is already resolved !
* Started working on using socket_*()


svn: 1404

Bryan Drewery 21 лет назад
Родитель
Сommit
82866c465d
4 измененных файлов с 94 добавлено и 39 удалено
  1. 72 25
      src/net.c
  2. 2 1
      src/net.h
  3. 1 13
      src/socket.c
  4. 19 0
      src/socket.h

+ 72 - 25
src/net.c

@@ -7,6 +7,7 @@
 #include <fcntl.h>
 #include "common.h"
 #include "net.h"
+#include "socket.h"
 #include "misc.h"
 #include "main.h"
 #include "debug.h"
@@ -267,6 +268,11 @@ in_addr_t getmyip() {
   return natip[0] ? inet_addr(natip) : cached_myip4_so.sin.sin_addr.s_addr;
 }
 
+in_addr_t getmyip6() {
+  return cached_myip6_so.sin.sin_addr.s_addr;
+}
+
+
 /* see if it's necessary to set inaddr_any... because if we can't resolve, we die anyway */
 void cache_my_ip()
 {
@@ -540,6 +546,34 @@ static int proxy_connect(int sock, char *host, int port, int proxy)
   return sock;
 }
 
+/* FIXME: REPLACE WITH SOCK_NAME() */
+void initialize_sockaddr(int af_type, const char *host, port_t port, union sockaddr_union *so)
+{
+    egg_bzero(so, sizeof(*so));
+
+    so->sa.sa_family = af_type;
+
+    if (af_type == AF_INET) {
+      so->sin.sin_family = AF_INET;
+      if (host) {
+        inet_pton(AF_INET, host, &so->sin.sin_addr);
+        so->sin.sin_port = htons(port);
+      } else {
+        so->sin.sin_addr.s_addr = getmyip();
+      }
+#ifdef USE_IPV6
+    } else {
+      so->sin6.sin6_family = AF_INET6;
+      if (host) {
+        inet_pton(AF_INET6, host, &so->sin6.sin6_addr);
+        so->sin6.sin6_port = htons(port);
+      } else {
+        memcpy(&so->sin6.sin6_addr, &cached_myip6_so.sin6.sin6_addr, 16);
+       }
+#endif /* USE_IPV6 */
+    }
+}
+
 /* Starts a connection attempt to a socket
  * 
  * If given a normal hostname, this will be resolved to the corresponding
@@ -556,6 +590,7 @@ int open_telnet_raw(int sock, char *server, port_t sport)
   union sockaddr_union so;
   char host[121] = "";
   volatile int proxy;
+  int is_resolved = 0;
 
   /* firewall?  use socks */
   if (firewall[0]) {
@@ -576,36 +611,48 @@ int open_telnet_raw(int sock, char *server, port_t sport)
     port = sport;
   }
 
-  if (!setjmp(alarmret)) {
-    alarm(resolve_timeout);
+  /* figure out which ip to bind to locally (v4 or v6) based on what the host ip is .. */
+  if ((is_resolved = is_dotted_ip(server))) {	/* already resolved */
+    sdprintf("IP addr passed to open_telnet");
+    initialize_sockaddr(is_resolved, NULL, 0, &so);
 
-    if (!get_ip(host, &so)) {
-      alarm(0);
-      /* ok, we resolved it, bind an appropriate ip */
+    if (bind(sock, &so.sa, SIZEOF_SOCKADDR(so)) < 0)
+      return -1;
+
+    initialize_sockaddr(is_resolved, host, port, &so);
+
+  } else {	/* if not resolved, resolve it with blocking calls.. (shouldn't happen ever) */
+    sdprintf("WARNING: open_telnet_raw() is about to block in get_ip()!");
+
+    if (!setjmp(alarmret)) {
+      alarm(resolve_timeout);
+      if (!get_ip(host, &so)) {
+        alarm(0);
+        /* ok, we resolved it, bind an appropriate ip */
 #ifdef USE_IPV6
-      if (so.sa.sa_family == AF_INET6) {
-        if (bind(sock, &cached_myip6_so.sa, SIZEOF_SOCKADDR(cached_myip6_so)) < 0) {
-          killsock(sock);
-          return -1;
-        }
-      } else {
+        if (so.sa.sa_family == AF_INET6) {
+          if (bind(sock, &cached_myip6_so.sa, SIZEOF_SOCKADDR(cached_myip6_so)) < 0) {
+            killsock(sock);
+            return -1;
+          }
+        } else {
 #endif /* USE_IPV6 */
-        if (bind(sock, &cached_myip4_so.sa, SIZEOF_SOCKADDR(cached_myip4_so)) < 0) {
-          killsock(sock);
-          return -3;
-        }
+          if (bind(sock, &cached_myip4_so.sa, SIZEOF_SOCKADDR(cached_myip4_so)) < 0) {
+            killsock(sock);
+            return -3;
+          }
 #ifdef USE_IPV6
-      }
-      if (so.sa.sa_family == AF_INET6)
-        so.sin6.sin6_port = htons(port);
-      else
+        }
+        if (so.sa.sa_family == AF_INET6)
+          so.sin6.sin6_port = htons(port);
+        else
 #endif /* USE_IPV6 */
-        so.sin.sin_port = htons(port);
-
-    } else {
-      alarm(0);
-      killsock(sock);
-      return -2;
+          so.sin.sin_port = htons(port);
+      } else {
+        alarm(0);
+        killsock(sock);
+        return -2;
+      }
     }
   }
 

+ 2 - 1
src/net.h

@@ -85,7 +85,7 @@ enum {
          (((u_int32_t *) (a))[2] == htonl (0xffff)))
 #endif /* !defined(IN6_IS_ADDR_V4MAPPED) */
 
-union sockaddr_union {
+union sockaddr_union {			/* replaced by sockname_t */
   struct sockaddr sa;
   struct sockaddr_in sin;
 #ifdef USE_IPV6
@@ -129,6 +129,7 @@ int ssl_link(int, int);
 #endif /* HAVE_SSL */
 char *myipstr(int);
 in_addr_t getmyip();
+in_addr_t getmyip6();
 void cache_my_ip();
 void setsock(int, int);
 int allocsock(int, int);

+ 1 - 13
src/socket.c

@@ -97,20 +97,8 @@ int egg_client(int idx, const char *host, int port, const char *vip, int vport,
 }
 */
 
-typedef struct {
-        int len;
-        int family;
-        union {
-                struct sockaddr addr;
-                struct sockaddr_in ipv4;
-#ifdef USE_IPV6
-                struct sockaddr_in6 ipv6;
-#endif
-        } u;
-} sockname_t;
-
 
-static int socket_name(sockname_t *name, const char *ipaddr, int port)
+int socket_name(sockname_t *name, const char *ipaddr, int port)
 {
         egg_bzero(name, sizeof(*name));
 

+ 19 - 0
src/socket.h

@@ -1,6 +1,8 @@
 #ifndef _SOCKET_H
 #define _SOCKET_H
 
+#include "types.h"
+
 #define SOCKET_CLIENT   1
 #define SOCKET_SERVER   2
 #define SOCKET_BIND     4
@@ -9,6 +11,23 @@
 #define SOCKET_UDP      32
 
 
+/* can be static if ever combined with net.h or a more integrated 1.9 is used ... */
+typedef struct {
+        int len;
+        int family;
+        union {
+                struct sockaddr addr;
+                struct sockaddr_in ipv4;
+#ifdef USE_IPV6
+                struct sockaddr_in6 ipv6;
+#endif
+        } u;
+} sockname_t;
+int socket_name(sockname_t *name, const char *ipaddr, port_t port);
+
+
+/* globals */
+
 int socket_create(const char *dest_ip, int dest_port, const char *src_ip, int src_port, int flags);
 //int socket_close(int sock);
 int socket_set_nonblock(int desc, int value);