Mercurial > hg > nnchat
diff libnnchat.c @ 354:c01e42fc9adb
More work on SOCKS proxy support, should work now.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Thu, 23 Jun 2011 08:26:48 +0300 |
parents | b54c8545dcb0 |
children | ba2aa110755b |
line wrap: on
line diff
--- 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);