Эх сурвалжийг харах

Better C proxy host resolution.

Use getaddrinfo instead of gethostbyname.
Joel Martin 15 жил өмнө
parent
commit
b0696c4473
2 өөрчлөгдсөн 32 нэмэгдсэн , 21 устгасан
  1. 27 11
      utils/websocket.c
  2. 5 10
      utils/wsproxy.c

+ 27 - 11
utils/websocket.c

@@ -12,8 +12,8 @@
 #include <sys/types.h> 
 #include <sys/socket.h>
 #include <netinet/in.h>
-#include <netdb.h>
 #include <arpa/inet.h>
+#include <netdb.h>
 #include <openssl/err.h>
 #include <openssl/ssl.h>
 #include <resolv.h>      /* base64 encode/decode */
@@ -55,6 +55,30 @@ void fatal(char *msg)
     exit(1);
 }
 
+/* resolve host with also IP address parsing */ 
+int resolve_host(struct in_addr *sin_addr, const char *hostname) 
+{ 
+    if (!inet_aton(hostname, sin_addr)) { 
+        struct addrinfo *ai, *cur; 
+        struct addrinfo hints; 
+        memset(&hints, 0, sizeof(hints)); 
+        hints.ai_family = AF_INET; 
+        if (getaddrinfo(hostname, NULL, &hints, &ai)) 
+            return -1; 
+        for (cur = ai; cur; cur = cur->ai_next) { 
+            if (cur->ai_family == AF_INET) { 
+                *sin_addr = ((struct sockaddr_in *)cur->ai_addr)->sin_addr; 
+                freeaddrinfo(ai); 
+                return 0; 
+            } 
+        } 
+        freeaddrinfo(ai); 
+        return -1; 
+    } 
+    return 0; 
+} 
+
+
 /*
  * SSL Wrapper Code
  */
@@ -331,7 +355,6 @@ void start_server(int listen_port,
                   char *listen_host) {
     int lsock, csock, clilen, sopt = 1, i;
     struct sockaddr_in serv_addr, cli_addr;
-    struct hostent *lhost;
     ws_ctx_t *ws_ctx;
 
     /* Initialize buffers */
@@ -355,15 +378,8 @@ void start_server(int listen_port,
     if ((listen_host == NULL) || (listen_host[0] == '\0')) {
         serv_addr.sin_addr.s_addr = INADDR_ANY;
     } else {
-        lhost = gethostbyname(listen_host);
-        if (lhost == NULL) {
-            fatal("Could not resolve self address");
-        }
-        bcopy((char *) lhost->h_addr,
-            (char *) &serv_addr.sin_addr.s_addr,
-            lhost->h_length);
-        for (i=0; i < strlen(lhost->h_addr); i++) {
-            printf("%d: %d\n", i, lhost->h_addr[i]);
+        if (resolve_host(&serv_addr.sin_addr, listen_host) < -1) {
+            fatal("Could not resolve listen address");
         }
     }
 

+ 5 - 10
utils/wsproxy.c

@@ -193,7 +193,6 @@ void do_proxy(ws_ctx_t *ws_ctx, int target) {
 void proxy_handler(ws_ctx_t *ws_ctx) {
     int tsock = 0;
     struct sockaddr_in taddr;
-    struct hostent *thost;
 
     printf("Connecting to: %s:%d\n", target_host, target_port);
 
@@ -202,19 +201,15 @@ void proxy_handler(ws_ctx_t *ws_ctx) {
         error("Could not create target socket");
         return;
     }
-    thost = gethostbyname(target_host);
-    if (thost == NULL) {
-        error("Could not resolve server");
-        close(tsock);
-        return;
-    }
     bzero((char *) &taddr, sizeof(taddr));
     taddr.sin_family = AF_INET;
-    bcopy((char *) thost->h_addr,
-          (char *) &taddr.sin_addr.s_addr,
-          thost->h_length);
     taddr.sin_port = htons(target_port);
 
+    /* Resolve target address */
+    if (resolve_host(&taddr.sin_addr, target_host) < -1) {
+        fatal("Could not resolve target address");
+    }
+
     if (connect(tsock, (struct sockaddr *) &taddr, sizeof(taddr)) < 0) {
         error("Could not connect to target");
         close(tsock);