comparison 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
comparison
equal deleted inserted replaced
351:b18b97d3e4f5 352:b54c8545dcb0
37 #define SET_MAX_WINDOWS (32) 37 #define SET_MAX_WINDOWS (32)
38 38
39 39
40 /* Options 40 /* Options
41 */ 41 */
42 int optPort = 8005; 42 int optPort = 8005,
43 optProxyPort = 1080,
44 optProxyType = NN_PROXY_NONE;
43 int optUserColor = 0x000000; 45 int optUserColor = 0x000000;
44 char *optServer = "chat.newbienudes.com", 46 char *optServer = "chat.newbienudes.com",
47 *optProxyServer = NULL,
45 *optUserName = NULL, 48 *optUserName = NULL,
46 *optUserNameCmd = NULL, 49 *optUserNameCmd = NULL,
47 *optUserNameEnc = NULL, 50 *optUserNameEnc = NULL,
48 *optPassword = NULL, 51 *optPassword = NULL,
49 *optPasswordCmd = NULL, 52 *optPasswordCmd = NULL,
87 { 2, 'p', "port", "Connect to port", OPT_ARGREQ }, 90 { 2, 'p', "port", "Connect to port", OPT_ARGREQ },
88 { 3, 's', "server", "Server to connect to", OPT_ARGREQ }, 91 { 3, 's', "server", "Server to connect to", OPT_ARGREQ },
89 { 4, 'C', "color", "Initial color in RGB hex 000000", OPT_ARGREQ }, 92 { 4, 'C', "color", "Initial color in RGB hex 000000", OPT_ARGREQ },
90 { 5, 'l', "logfile", "Log filename", OPT_ARGREQ }, 93 { 5, 'l', "logfile", "Log filename", OPT_ARGREQ },
91 { 6, 'D', "daemon", "A pseudo-daemon mode for logging", OPT_NONE }, 94 { 6, 'D', "daemon", "A pseudo-daemon mode for logging", OPT_NONE },
92 { 7, 'S', "site", "Site (default: NN)", OPT_ARGREQ }, 95 { 7, 'f', "force-site", "Force site (default: NN)", OPT_ARGREQ },
93 { 8, 'd', "debug", "Enable various debug features", OPT_NONE }, 96 { 8, 'd', "debug", "Enable various debug features", OPT_NONE },
97
98 {10, '4', "socks4", "SOCKS4 proxy server", OPT_ARGREQ },
99 {11, 'A', "socks4a", "SOCKS4A proxy server", OPT_ARGREQ },
100 {12, 'P', "proxy-port", "Proxy port (default: 1080)", OPT_ARGREQ },
94 }; 101 };
95 102
96 const int optListN = (sizeof(optList) / sizeof(optList[0])); 103 const int optListN = (sizeof(optList) / sizeof(optList[0]));
97 104
98 105
148 155
149 case 8: 156 case 8:
150 optDebug = TRUE; 157 optDebug = TRUE;
151 THMSG(1, "Debug mode enabled.\n"); 158 THMSG(1, "Debug mode enabled.\n");
152 break; 159 break;
160
161
162 case 10:
163 optProxyServer = optArg;
164 optProxyType = NN_PROXY_SOCKS4;
165 break;
166
167 case 11:
168 optProxyServer = optArg;
169 optProxyType = NN_PROXY_SOCKS4A;
170 break;
171
172 case 12:
173 optPort = atoi(optArg);
174 break;
175
153 176
154 default: 177 default:
155 THERR("Unknown option '%s'.\n", currArg); 178 THERR("Unknown option '%s'.\n", currArg);
156 return FALSE; 179 return FALSE;
157 } 180 }
1247 } 1270 }
1248 1271
1249 int main(int argc, char *argv[]) 1272 int main(int argc, char *argv[])
1250 { 1273 {
1251 nn_conn_t *conn = NULL; 1274 nn_conn_t *conn = NULL;
1252 struct hostent *tmpHost; 1275 struct hostent *tmpHost = NULL, *proxyHost = NULL;
1253 int curVis = ERR, updateCount = 0; 1276 int curVis = ERR, updateCount = 0;
1254 BOOL argsOK, isError = FALSE, 1277 BOOL argsOK, isError = FALSE,
1255 exitProg = FALSE, 1278 exitProg = FALSE,
1256 colorSet = FALSE, 1279 colorSet = FALSE,
1257 cursesInit = FALSE, 1280 cursesInit = FALSE,
1427 if (optUserName == NULL || optPassword == NULL) { 1450 if (optUserName == NULL || optPassword == NULL) {
1428 errorMsg("Username and/or password not specified.\n"); 1451 errorMsg("Username and/or password not specified.\n");
1429 goto err_exit; 1452 goto err_exit;
1430 } 1453 }
1431 1454
1455 /* Are we using a proxy? */
1456 if (optProxyType != NN_PROXY_NONE && optProxyServer != NULL) {
1457 printMsg(currWin, "Trying to resolve proxy host '%s' ...\n", optProxyServer);
1458 tmpHost = gethostbyname(optProxyServer);
1459 if (tmpHost == NULL) {
1460 errorMsg("Could not resolve hostname: %s.\n", strerror(h_errno));
1461 goto err_exit;
1462 }
1463 printMsg(currWin, "True hostname: %s\n", tmpHost->h_name);
1464 }
1465
1432 /* Okay ... */ 1466 /* Okay ... */
1433 printMsg(currWin, "Trying to resolve host '%s' ...\n", optServer); 1467 printMsg(currWin, "Trying to resolve host '%s' ...\n", optServer);
1434 tmpHost = gethostbyname(optServer); 1468 tmpHost = gethostbyname(optServer);
1435 if (tmpHost == NULL) { 1469 if (tmpHost == NULL) {
1436 errorMsg("Could not resolve hostname: %s.\n", strerror(h_errno)); 1470 errorMsg("Could not resolve hostname: %s.\n", strerror(h_errno));
1440 1474
1441 #ifdef FINAL_BUILD 1475 #ifdef FINAL_BUILD
1442 /* To emulate the official client, we first make a request for 1476 /* To emulate the official client, we first make a request for
1443 * policy file, even though we don't use it for anything... 1477 * policy file, even though we don't use it for anything...
1444 */ 1478 */
1445 conn = nn_conn_open((struct in_addr *) tmpHost->h_addr, 843); 1479 conn = nn_conn_open(errorFunc, messageFunc,
1480 optProxyType, optProxyPort, proxyHost != NULL ? (struct in_addr *) proxyHost->h_addr : NULL,
1481 (struct in_addr *) tmpHost->h_addr, 843, optServer);
1482
1446 if (!nn_conn_check(conn)) { 1483 if (!nn_conn_check(conn)) {
1447 errorMsg("Policy file request connection setup failed!\n"); 1484 errorMsg("Policy file request connection setup failed!\n");
1448 goto err_exit; 1485 goto err_exit;
1449 } 1486 }
1450 1487
1462 } 1499 }
1463 nn_conn_close(conn); 1500 nn_conn_close(conn);
1464 #endif 1501 #endif
1465 1502
1466 /* Okay, now do the proper connection ... */ 1503 /* Okay, now do the proper connection ... */
1467 conn = nn_conn_open((struct in_addr *) tmpHost->h_addr, optPort); 1504 conn = nn_conn_open(errorFunc, messageFunc,
1505 optProxyType, optProxyPort, proxyHost != NULL ? (struct in_addr *) proxyHost->h_addr : NULL,
1506 (struct in_addr *) tmpHost->h_addr, optPort, optServer);
1507
1468 if (!nn_conn_check(conn)) { 1508 if (!nn_conn_check(conn)) {
1469 errorMsg("Main connection setup failed!\n"); 1509 errorMsg("Main connection setup failed!\n");
1470 goto err_exit; 1510 goto err_exit;
1471 } 1511 }
1472 1512
1473 conn->errfunc = errorFunc;
1474 conn->msgfunc = messageFunc;
1475
1476 /* Send login command */ 1513 /* Send login command */
1477 optUserNameEnc = nn_dblencode_str(optUserName); 1514 optUserNameEnc = nn_dblencode_str(optUserName);
1478 tmpStr = nn_dblencode_str(optSite); 1515 tmpStr = nn_dblencode_str(optSite);
1479 nn_conn_send_msg(conn, optUserNameEnc, "%%2Flogin%%20%%2Dsite%%20%s%%20%%2Dpassword%%20%s", tmpStr, optPassword); 1516 nn_conn_send_msg(conn, optUserNameEnc, "%%2Flogin%%20%%2Dsite%%20%s%%20%%2Dpassword%%20%s", tmpStr, optPassword);
1480 th_free(tmpStr); 1517 th_free(tmpStr);