# HG changeset patch # User Matti Hamalainen # Date 1308806808 -10800 # Node ID c01e42fc9adbca99a7007f64b82e1d75628e41e1 # Parent 83ae825bb8c1b7b4f79aff67131632b2dd071fee More work on SOCKS proxy support, should work now. diff -r 83ae825bb8c1 -r c01e42fc9adb libnnchat.c --- a/libnnchat.c Thu Jun 23 06:31:34 2011 +0300 +++ b/libnnchat.c Thu Jun 23 08:26:48 2011 +0300 @@ -72,6 +72,17 @@ } } +struct hostent *nn_resolve_host(nn_conn_t *conn, const char *name) +{ + struct hostent *res = gethostbyname(name); + if (res == NULL) + nn_conn_err(conn, "Could not resolve hostname: %s\n", strerror(h_errno)); + else + nn_conn_msg(conn, "True hostname for %s is %s\n", name, res->h_name); + + return res; +} + static const char *nn_proxy_types[] = { "none", "SOCKS 4", @@ -79,51 +90,78 @@ NULL }; -nn_conn_t * nn_conn_open( - void (*errfunc)(struct _nn_conn_t *conn, const char *fmt, va_list ap), - void (*msgfunc)(struct _nn_conn_t *conn, const char *fmt, va_list ap), - int ptype, int pport, struct in_addr *paddr, - struct in_addr *addr, const int port, const char *host) + +nn_conn_t * nn_conn_new( + void (*errfunc)(nn_conn_t *conn, const char *fmt, va_list ap), + void (*msgfunc)(nn_conn_t *conn, const char *fmt, va_list ap)) { nn_conn_t *conn = th_calloc(1, sizeof(nn_conn_t)); + + if (conn == NULL) + return NULL; + + conn->errfunc = errfunc; + conn->msgfunc = msgfunc; + + return conn; +} + +int nn_conn_set_proxy(nn_conn_t *conn, int type, int port, const char *host) +{ + if (conn == NULL) + return -1; + + conn->proxy.type = type; + conn->proxy.port = port; + conn->proxy.host = th_strdup(host); + + if (host != NULL) { + conn->proxy.hst = nn_resolve_host(conn, host); + if (conn->proxy.hst != NULL) + conn->proxy.addr = *(struct in_addr *) (conn->proxy.hst->h_addr); + else { + conn->proxy.addr.s_addr = 0; + } + } else + return -2; + + return 0; +} + +int nn_conn_open(nn_conn_t *conn, const int port, const char *host) +{ struct sockaddr_in dest; static const char *userid = "James Bond"; if (conn == NULL) - return NULL; - - /* Initialize data */ - conn->errfunc = errfunc; - conn->msgfunc = msgfunc; - - conn->proxy.type = ptype; - conn->proxy.port = pport; - if (paddr != NULL) - conn->proxy.addr = *paddr; + return -1; conn->port = port; - conn->addr = *addr; + if (host != NULL) { + conn->host = th_strdup(host); + conn->hst = nn_resolve_host(conn, host); + } - if (ptype == NN_PROXY_SOCKS4A && host == NULL) { - nn_conn_err(conn, "Host string NULL and proxy type SOCKS 4a specified. Using IP address instead.\n"); - conn->host = th_strdup(inet_ntoa(dest.sin_addr)); - } else - conn->host = th_strdup(host); + if (conn->hst != NULL) + conn->addr = *(struct in_addr *) (conn->hst->h_addr); + else { + conn->addr.s_addr = 0; + } /* Prepare for connection */ - if (ptype > NN_PROXY_NONE && ptype < NN_PROXY_LAST) { + if (conn->proxy.type > NN_PROXY_NONE && conn->proxy.type < NN_PROXY_LAST) { dest.sin_family = AF_INET; - dest.sin_port = htons(pport); + dest.sin_port = htons(conn->proxy.port); dest.sin_addr = conn->proxy.addr; nn_conn_msg(conn, "Connecting to %s proxy %s:%d ...\n", - nn_proxy_types[ptype], + nn_proxy_types[conn->proxy.type], inet_ntoa(dest.sin_addr), port); } else { dest.sin_family = AF_INET; dest.sin_port = htons(port); - dest.sin_addr = *addr; + dest.sin_addr = conn->addr; nn_conn_msg(conn, "Connecting to %s:%d ...\n", inet_ntoa(dest.sin_addr), port); @@ -147,7 +185,7 @@ FD_SET(conn->socket, &(conn->sockfds)); /* Proxy-specific setup */ - if (ptype == NN_PROXY_SOCKS4 || ptype == NN_PROXY_SOCKS4A) { + if (conn->proxy.type == NN_PROXY_SOCKS4 || conn->proxy.type == NN_PROXY_SOCKS4A) { struct nn_socks_t *socksh; size_t bufsiz = sizeof(struct nn_socks_t) + strlen(userid) + 1 + strlen(conn->host) + 1; char *ptr, *buf; @@ -163,13 +201,13 @@ /* Create SOCKS 4/4A request */ nn_conn_msg(conn, "Initializing proxy negotiation.\n"); socksh = (struct nn_socks_t *) buf; - socksh->version = (ptype == NN_PROXY_SOCKS4) ? 4 : 5; + socksh->version = 4; socksh->command = SOCKS_CMD_CONNECT; socksh->port = htons(port); - if (ptype == NN_PROXY_SOCKS4A) + if (conn->proxy.type == NN_PROXY_SOCKS4A) socksh->addr = htonl(0x00000032); else - socksh->addr = dest.sin_addr.s_addr; + socksh->addr = conn->addr.s_addr; ptr += sizeof(struct nn_socks_t); strcpy(ptr, userid); @@ -215,11 +253,11 @@ } conn->status = NN_CONN_OPEN; - return conn; + return 0; error: conn->status = NN_CONN_CLOSED; - return conn; + return -2; } @@ -236,7 +274,10 @@ #endif conn->socket = -1; } - + + th_free(conn->host); + th_free(conn->proxy.host); + conn->status = NN_CONN_CLOSED; th_free(conn); diff -r 83ae825bb8c1 -r c01e42fc9adb libnnchat.h --- a/libnnchat.h Thu Jun 23 06:31:34 2011 +0300 +++ b/libnnchat.h Thu Jun 23 08:26:48 2011 +0300 @@ -68,14 +68,18 @@ typedef struct _nn_conn_t { struct { + char *host; + struct hostent *hst; int type; int port; struct in_addr addr; } proxy; char *host; + struct hostent *hst; + int port; + int socket; - int port; struct in_addr addr; fd_set sockfds; @@ -95,11 +99,13 @@ BOOL nn_network_init(); void nn_network_close(void); -nn_conn_t * nn_conn_open( - void (*errfunc)(struct _nn_conn_t *conn, const char *fmt, va_list ap), - void (*msgfunc)(struct _nn_conn_t *conn, const char *fmt, va_list ap), - int ptype, int pport, struct in_addr *paddr, - struct in_addr *addr, const int port, const char *host); +struct hostent *nn_resolve_host(nn_conn_t *conn, const char *name); +nn_conn_t * nn_conn_new( + void (*errfunc)(nn_conn_t *conn, const char *fmt, va_list ap), + void (*msgfunc)(nn_conn_t *conn, const char *fmt, va_list ap)); + +int nn_conn_set_proxy(nn_conn_t *conn, int type, int port, const char *host); +int nn_conn_open(nn_conn_t *conn, const int port, const char *host); void nn_conn_close(nn_conn_t *); int nn_conn_pull(nn_conn_t *); BOOL nn_conn_send_buf(nn_conn_t *, const char *buf, const size_t len); diff -r 83ae825bb8c1 -r c01e42fc9adb nnchat.c --- a/nnchat.c Thu Jun 23 06:31:34 2011 +0300 +++ b/nnchat.c Thu Jun 23 08:26:48 2011 +0300 @@ -569,7 +569,7 @@ void messageFunc(struct _nn_conn_t *conn, const char *fmt, va_list ap) { (void) conn; - printMsgV(chatWindows[0], LOG_STAMP | LOG_WINDOW | LOG_FILE, fmt, ap); + printMsgV(NULL, LOG_STAMP | LOG_WINDOW | LOG_FILE, fmt, ap); } @@ -1272,7 +1272,6 @@ int main(int argc, char *argv[]) { nn_conn_t *conn = NULL; - struct hostent *tmpHost = NULL, *proxyHost = NULL; int curVis = ERR, updateCount = 0; BOOL argsOK, isError = FALSE, exitProg = FALSE, @@ -1461,35 +1460,35 @@ goto err_exit; } + /* Create a connection */ + conn = nn_conn_new(errorFunc, messageFunc); + if (conn == NULL) { + errorMsg("Could not create connection structure.\n"); + 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)); + if (nn_conn_set_proxy(conn, optProxyType, optProxyPort, optProxyServer) != 0) { + errorMsg("Error setting proxy information.\n"); 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); - if (tmpHost == NULL) { + conn->host = th_strdup(optServer); + conn->hst = nn_resolve_host(conn, optServer); + if (conn->hst == NULL) { errorMsg("Could not resolve hostname: %s.\n", strerror(h_errno)); goto err_exit; } - printMsg(currWin, "True hostname: %s\n", tmpHost->h_name); #ifdef FINAL_BUILD /* 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(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)) { + if (nn_conn_open(conn, 843, NULL) != 0) { errorMsg("Policy file request connection setup failed!\n"); goto err_exit; } @@ -1510,11 +1509,7 @@ #endif /* Okay, now do the proper connection ... */ - 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)) { + if (nn_conn_open(conn, optPort, NULL) != 0) { errorMsg("Main connection setup failed!\n"); goto err_exit; }