diff nnchat.c @ 352:b54c8545dcb0

Overhaul network code a bit, add initial implementation of SOCKS4/4A proxy support -- which may not work yet, it is untested.
author Matti Hamalainen <ccr@tnsp.org>
date Thu, 23 Jun 2011 06:28:40 +0300
parents 34e3705b382c
children 83ae825bb8c1
line wrap: on
line diff
--- a/nnchat.c	Thu Jun 23 04:39:10 2011 +0300
+++ b/nnchat.c	Thu Jun 23 06:28:40 2011 +0300
@@ -39,9 +39,12 @@
 
 /* Options
  */
-int     optPort = 8005;
+int     optPort = 8005,
+        optProxyPort = 1080,
+        optProxyType = NN_PROXY_NONE;
 int     optUserColor = 0x000000;
 char    *optServer = "chat.newbienudes.com",
+        *optProxyServer = NULL,
         *optUserName = NULL,
         *optUserNameCmd = NULL,
         *optUserNameEnc = NULL,
@@ -89,8 +92,12 @@
     { 4, 'C', "color",      "Initial color in RGB hex 000000", OPT_ARGREQ },
     { 5, 'l', "logfile",    "Log filename", OPT_ARGREQ },
     { 6, 'D', "daemon",     "A pseudo-daemon mode for logging", OPT_NONE },
-    { 7, 'S', "site",       "Site (default: NN)", OPT_ARGREQ },
+    { 7, 'f', "force-site", "Force site (default: NN)", OPT_ARGREQ },
     { 8, 'd', "debug",      "Enable various debug features", OPT_NONE },
+    
+    {10, '4', "socks4",     "SOCKS4 proxy server", OPT_ARGREQ },
+    {11, 'A', "socks4a",    "SOCKS4A proxy server", OPT_ARGREQ },
+    {12, 'P', "proxy-port", "Proxy port (default: 1080)", OPT_ARGREQ },
 };
 
 const int optListN = (sizeof(optList) / sizeof(optList[0]));
@@ -151,6 +158,22 @@
         THMSG(1, "Debug mode enabled.\n");
         break;
 
+
+    case 10:
+        optProxyServer = optArg;
+        optProxyType = NN_PROXY_SOCKS4;
+        break;
+
+    case 11:
+        optProxyServer = optArg;
+        optProxyType = NN_PROXY_SOCKS4A;
+        break;
+
+    case 12:
+        optPort = atoi(optArg);
+        break;
+
+
     default:
         THERR("Unknown option '%s'.\n", currArg);
         return FALSE;
@@ -1249,7 +1272,7 @@
 int main(int argc, char *argv[])
 {
     nn_conn_t *conn = NULL;
-    struct hostent *tmpHost;
+    struct hostent *tmpHost = NULL, *proxyHost = NULL;
     int curVis = ERR, updateCount = 0;
     BOOL argsOK, isError = FALSE,
         exitProg = FALSE,
@@ -1429,6 +1452,17 @@
         goto err_exit;
     }
 
+    /* Are we using a proxy? */
+    if (optProxyType != NN_PROXY_NONE && optProxyServer != NULL) {
+        printMsg(currWin, "Trying to resolve proxy host '%s' ...\n", optProxyServer);
+        tmpHost = gethostbyname(optProxyServer);
+        if (tmpHost == NULL) {
+            errorMsg("Could not resolve hostname: %s.\n", strerror(h_errno));
+            goto err_exit;
+        }
+        printMsg(currWin, "True hostname: %s\n", tmpHost->h_name);
+    }
+    
     /* Okay ... */
     printMsg(currWin, "Trying to resolve host '%s' ...\n", optServer);
     tmpHost = gethostbyname(optServer);
@@ -1442,7 +1476,10 @@
     /* To emulate the official client, we first make a request for
      * policy file, even though we don't use it for anything...
      */
-    conn = nn_conn_open((struct in_addr *) tmpHost->h_addr, 843);
+    conn = nn_conn_open(errorFunc, messageFunc,
+        optProxyType, optProxyPort, proxyHost != NULL ? (struct in_addr *) proxyHost->h_addr : NULL,
+        (struct in_addr *) tmpHost->h_addr, 843, optServer);
+
     if (!nn_conn_check(conn)) {
         errorMsg("Policy file request connection setup failed!\n");
         goto err_exit;
@@ -1464,15 +1501,15 @@
 #endif
 
     /* Okay, now do the proper connection ... */
-    conn = nn_conn_open((struct in_addr *) tmpHost->h_addr, optPort);
+    conn = nn_conn_open(errorFunc, messageFunc,
+        optProxyType, optProxyPort, proxyHost != NULL ? (struct in_addr *) proxyHost->h_addr : NULL,
+        (struct in_addr *) tmpHost->h_addr, optPort, optServer);
+
     if (!nn_conn_check(conn)) {
         errorMsg("Main connection setup failed!\n");
         goto err_exit;
     }
     
-    conn->errfunc = errorFunc;
-    conn->msgfunc = messageFunc;
-
     /* Send login command */
     optUserNameEnc = nn_dblencode_str(optUserName);
     tmpStr = nn_dblencode_str(optSite);