# HG changeset patch # User Matti Hamalainen # Date 1404429506 -10800 # Node ID 11fa2bf902510d63320fc46398a777d32ebf6080 # Parent 6624893ad528ec220633a0e770568f54c3cd98c0 Network API changes due to preparation for fixes in proxy support. diff -r 6624893ad528 -r 11fa2bf90251 th_network.c --- a/th_network.c Mon Jun 23 16:59:36 2014 +0300 +++ b/th_network.c Fri Jul 04 02:18:26 2014 +0300 @@ -99,9 +99,10 @@ if (res == NULL) { - th_conn_err(conn, h_errno, + int err = th_errno_to_error(h_errno); + th_conn_err(conn, err, "Could not resolve hostname '%s': %s\n", - name, th_error_str(h_errno)); + name, th_error_str(err)); } else { @@ -113,6 +114,17 @@ } +BOOL th_base_conn_init(th_base_conn_t *base, ssize_t bufsize) +{ + // Allocate connection data buffer + base->bufsize = (bufsize <= 0) ? TH_CONNBUF_SIZE : bufsize; + if ((base->buf = th_malloc(base->bufsize)) == NULL) + return FALSE; + + return TRUE; +} + + th_conn_t * th_conn_new( void (*errfunc)(th_conn_t *conn, int err, const char *msg), void (*msgfunc)(th_conn_t *conn, int loglevel, const char *msg), @@ -127,9 +139,8 @@ conn->errfunc = errfunc; conn->msgfunc = msgfunc; - // Allocate connection data buffer - conn->bufsize = (bufsize <= 0) ? TH_CONNBUF_SIZE : bufsize; - if ((conn->buf = th_malloc(conn->bufsize)) == NULL) + // Do base initialization + if (!th_base_conn_init(&conn->base, bufsize)) { th_free(conn); return NULL; @@ -160,16 +171,16 @@ return THERR_NULLPTR; conn->proxy.type = type; - conn->proxy.port = port; conn->proxy.auth_type = auth_type; - th_free(conn->proxy.host); - conn->proxy.host = th_strdup(host); + conn->proxy.conn.port = port; + th_free(conn->proxy.conn.host); + conn->proxy.conn.host = th_strdup(host); if (host != NULL) { - conn->proxy.hst = th_resolve_host(conn, host); - th_get_addr(&(conn->proxy.addr), conn->proxy.hst); + conn->proxy.conn.hst = th_resolve_host(conn, host); + th_get_addr(&(conn->proxy.conn.addr), conn->proxy.conn.hst); } else return THERR_INVALID_DATA; @@ -236,7 +247,7 @@ case TH_CONN_DATA_AVAIL: case TH_CONN_NO_DATA: - if (conn->total_bytes < want) + if (conn->base.total_bytes < want) status = TH_CONN_NO_DATA; break; @@ -287,7 +298,7 @@ switch (conn->proxy.addr_type) { case TH_PROXY_ADDR_IPV4: - th_growbuf_put_str(&buf, (uint8_t *) &(conn->addr.s_addr), sizeof(conn->addr.s_addr)); + th_growbuf_put_str(&buf, (uint8_t *) &(conn->base.addr.s_addr), sizeof(conn->base.addr.s_addr)); break; case TH_PROXY_ADDR_DOMAIN: @@ -321,7 +332,7 @@ if (th_conn_proxy_wait(conn, 2) != TH_CONN_DATA_AVAIL) goto out; - ptr = (uint8_t*) conn->buf; + ptr = (uint8_t*) conn->base.buf; if (*ptr != 0) { err = THERR_INIT_FAIL; @@ -359,8 +370,8 @@ static int th_conn_socks5_negotiate(th_conn_t *conn, const int port, const char *host) { th_growbuf_t buf; - uint8_t *ptr; - int cmd, avail, auth, err = THERR_INIT_FAIL; + uint8_t *ptr, authlist[16]; + int i, cmd, avail, auth, err = THERR_INIT_FAIL; th_growbuf_init(&buf, 256); th_conn_msg(conn, THLOG_INFO, "Initializing SOCKS 5 proxy negotiation.\n"); @@ -376,16 +387,11 @@ goto out; } + avail = 0; switch (conn->proxy.auth_type) { - case TH_PROXY_AUTH_NONE: - avail = 1; - auth = SOCKS5_AUTH_NONE; - break; - case TH_PROXY_AUTH_USER: - avail = 2; - auth = SOCKS5_AUTH_USER; + authlist[avail++] = SOCKS5_AUTH_USER; if (conn->proxy.userid == NULL || conn->proxy.passwd == NULL) { err = THERR_INVALID_DATA; @@ -402,6 +408,10 @@ "SOCKS 5 proxy userid or password is too long.\n"); goto out; } + //break; + + case TH_PROXY_AUTH_NONE: + authlist[avail++] = SOCKS5_AUTH_NONE; break; default: @@ -416,7 +426,8 @@ th_growbuf_clear(&buf); th_growbuf_put_u8(&buf, 0x05); // Protocol version th_growbuf_put_u8(&buf, avail); // # of available auth methods - th_growbuf_put_u8(&buf, auth); + for (i = 0; i < avail; i++) + th_growbuf_put_u8(&buf, authlist[i]); // Send request if ((err = th_conn_proxy_send(conn, &buf)) != THERR_OK) @@ -426,7 +437,7 @@ if (th_conn_proxy_wait(conn, 2) != TH_CONN_DATA_AVAIL) goto out; - ptr = (uint8_t *) conn->buf; + ptr = (uint8_t *) conn->base.buf; if (*ptr != 0x05) { err = THERR_INVALID_DATA; @@ -465,7 +476,7 @@ if (th_conn_proxy_wait(conn, 2) != TH_CONN_DATA_AVAIL) goto out; - ptr = (uint8_t *) conn->buf; + ptr = (uint8_t *) conn->base.buf; if (*ptr != 0x01) { err = THERR_INVALID_DATA; @@ -507,12 +518,12 @@ { case TH_PROXY_ADDR_IPV4: th_growbuf_put_u8(&buf, SOCKS5_ADDR_IPV4); - th_growbuf_put_str(&buf, (uint8_t *) &(conn->addr.s_addr), sizeof(conn->addr.s_addr)); + th_growbuf_put_str(&buf, (uint8_t *) &(conn->base.addr.s_addr), sizeof(conn->base.addr.s_addr)); break; case TH_PROXY_ADDR_IPV6: th_growbuf_put_u8(&buf, SOCKS5_ADDR_IPV6); - //th_growbuf_put_str(&buf, (uint8_t *) &(conn->addr.s_addr), sizeof(conn->addr.s_addr)); + //th_growbuf_put_str(&buf, (uint8_t *) &(conn->base.addr.s_addr), sizeof(conn->base.addr.s_addr)); break; case TH_PROXY_ADDR_DOMAIN: @@ -541,7 +552,7 @@ if (th_conn_proxy_wait(conn, 3) != TH_CONN_DATA_AVAIL) goto out; - ptr = (uint8_t *) conn->buf; + ptr = (uint8_t *) conn->base.buf; if (*ptr != 0x05) { err = THERR_INVALID_DATA; @@ -583,15 +594,15 @@ if (conn == NULL) return THERR_NULLPTR; - conn->port = port; - conn->host = th_strdup(host); - conn->hst = th_resolve_host(conn, host); + conn->base.port = port; + conn->base.host = th_strdup(host); + conn->base.hst = th_resolve_host(conn, host); // If name resolving locally fails, force to domain addr type - if (conn->hst == NULL) + if (conn->base.hst == NULL) conn->proxy.addr_type = TH_PROXY_ADDR_DOMAIN; - th_get_addr(&(conn->addr), conn->hst); + th_get_addr(&(conn->base.addr), conn->base.hst); // Prepare for connection dest.sin_family = AF_INET; @@ -599,38 +610,38 @@ if (conn->proxy.type > TH_PROXY_NONE && conn->proxy.type < TH_PROXY_LAST) { // If using a proxy, we connect to the proxy server - dest.sin_port = htons(conn->proxy.port); - dest.sin_addr = conn->proxy.addr; + dest.sin_port = htons(conn->proxy.conn.port); + dest.sin_addr = conn->proxy.conn.addr; th_conn_msg(conn, THLOG_INFO, "Connecting to %s proxy %s:%d ...\n", th_proxy_types[conn->proxy.type], - inet_ntoa(conn->proxy.addr), conn->proxy.port); + inet_ntoa(conn->proxy.conn.addr), conn->proxy.conn.port); } else { - dest.sin_port = htons(conn->port); - dest.sin_addr = conn->addr; + dest.sin_port = htons(conn->base.port); + dest.sin_addr = conn->base.addr; th_conn_msg(conn, THLOG_INFO, "Connecting to %s:%d ...\n", - inet_ntoa(conn->addr), conn->port); + inet_ntoa(conn->base.addr), conn->base.port); } - if ((conn->socket = socket(PF_INET, SOCK_STREAM, 0)) == -1) + if ((conn->base.socket = socket(PF_INET, SOCK_STREAM, 0)) == -1) { err = th_errno_to_error(th_get_socket_errno()); th_conn_err(conn, err, "Could not open socket: %s\n", th_error_str(err)); goto error; } - if (connect(conn->socket, (struct sockaddr *) &dest, sizeof(dest)) == -1) + if (connect(conn->base.socket, (struct sockaddr *) &dest, sizeof(dest)) == -1) { err = th_errno_to_error(th_get_socket_errno()); th_conn_err(conn, err, "Could not connect: %s\n", th_error_str(err)); goto error; } - FD_ZERO(&(conn->sockfds)); - FD_SET(conn->socket, &(conn->sockfds)); + FD_ZERO(&(conn->base.sockfds)); + FD_SET(conn->base.socket, &(conn->base.sockfds)); // Proxy-specific setup switch (conn->proxy.type) @@ -668,14 +679,14 @@ if (conn == NULL) return -1; - if (conn->socket >= 0) + if (conn->base.socket >= 0) { #ifdef __WIN32 - closesocket(conn->socket); + closesocket(conn->base.socket); #else - close(conn->socket); + close(conn->base.socket); #endif - conn->socket = -1; + conn->base.socket = -1; } conn->status = TH_CONN_CLOSED; @@ -685,10 +696,10 @@ static void th_conn_free_nodelete(th_conn_t *conn) { - th_free(conn->buf); + th_free(conn->base.buf); th_conn_close(conn); - th_free(conn->host); - th_free(conn->proxy.host); + th_free(conn->base.host); + th_free(conn->proxy.conn.host); th_free(conn); } @@ -715,7 +726,7 @@ while (bufLeft > 0) { ssize_t bufSent; - bufSent = send(conn->socket, bufPtr, bufLeft, 0); + bufSent = send(conn->base.socket, bufPtr, bufLeft, 0); if (bufSent < 0) { int err = th_errno_to_error(th_get_socket_errno()); @@ -742,8 +753,8 @@ { if (conn != NULL) { - conn->ptr = conn->in_ptr = conn->buf; - conn->got_bytes = conn->total_bytes = 0; + conn->base.ptr = conn->base.in_ptr = conn->base.buf; + conn->base.got_bytes = conn->base.total_bytes = 0; } } @@ -758,16 +769,16 @@ return TH_CONN_ERROR; // Shift the input buffer - if (conn->ptr > conn->buf) + if (conn->base.ptr > conn->base.buf) { - size_t left = conn->in_ptr - conn->ptr; + size_t left = conn->base.in_ptr - conn->base.ptr; if (left > 0) { - size_t moved = conn->ptr - conn->buf; - memmove(conn->buf, conn->ptr, left); - conn->ptr = conn->buf; - conn->in_ptr -= moved; - conn->total_bytes -= moved; + size_t moved = conn->base.ptr - conn->base.buf; + memmove(conn->base.buf, conn->base.ptr, left); + conn->base.ptr = conn->base.buf; + conn->base.in_ptr -= moved; + conn->base.total_bytes -= moved; } else th_conn_reset(conn); @@ -776,9 +787,9 @@ // Check for incoming data socktv.tv_sec = 0; socktv.tv_usec = TH_DELAY_USEC; - tmpfds = conn->sockfds; + tmpfds = conn->base.sockfds; - if ((result = select(conn->socket + 1, &tmpfds, NULL, NULL, &socktv)) == -1) + if ((result = select(conn->base.socket + 1, &tmpfds, NULL, NULL, &socktv)) == -1) { int err = th_get_socket_errno(); if (err != EINTR) @@ -789,16 +800,18 @@ return TH_CONN_ERROR; } } - else if (FD_ISSET(conn->socket, &tmpfds)) + else if (FD_ISSET(conn->base.socket, &tmpfds)) { - conn->got_bytes = recv(conn->socket, conn->in_ptr, conn->bufsize - conn->total_bytes, 0); - if (conn->got_bytes < 0) + conn->base.got_bytes = recv(conn->base.socket, + conn->base.in_ptr, conn->base.bufsize - conn->base.total_bytes, 0); + + if (conn->base.got_bytes < 0) { int err = th_errno_to_error(th_get_socket_errno()); th_conn_err(conn, err, "Error in recv: %s\n", th_error_str(err)); return TH_CONN_ERROR; } - else if (conn->got_bytes == 0) + else if (conn->base.got_bytes == 0) { th_conn_err(conn, ECONNABORTED, "Server closed connection.\n"); conn->status = TH_CONN_CLOSED; @@ -806,8 +819,8 @@ } else { - conn->total_bytes += conn->got_bytes; - conn->in_ptr += conn->got_bytes; + conn->base.total_bytes += conn->base.got_bytes; + conn->base.in_ptr += conn->base.got_bytes; return TH_CONN_DATA_AVAIL; } } @@ -870,7 +883,7 @@ BOOL th_conn_buf_check(th_conn_t *conn, size_t n) { - return conn && (conn->ptr + n <= conn->in_ptr); + return conn && (conn->base.ptr + n <= conn->base.in_ptr); } @@ -878,7 +891,7 @@ { if (th_conn_buf_check(conn, n)) { - conn->ptr += n; + conn->base.ptr += n; return TRUE; } else @@ -892,9 +905,9 @@ if (!th_conn_buf_check(conn, n)) return -1; - if ((ret = strncmp(conn->ptr, str, n)) == 0) + if ((ret = strncmp(conn->base.ptr, str, n)) == 0) { - conn->ptr += n; + conn->base.ptr += n; return 0; } else @@ -913,9 +926,9 @@ char *pos; size_t n = strlen(str); - if (th_conn_buf_check(conn, n) && ((pos = strstr(conn->ptr, str)) != NULL)) + if (th_conn_buf_check(conn, n) && ((pos = strstr(conn->base.ptr, str)) != NULL)) { - conn->ptr = pos + n; + conn->base.ptr = pos + n; return pos; } else @@ -932,11 +945,11 @@ "\n--------------------------------------------------------------\n" "err=%d, status=%d, got_bytes=%d, total_bytes=%d\n" "buf=0x%p, in_ptr=0x%04x, ptr=0x%04x\n", - conn->err, conn->status, conn->got_bytes, conn->total_bytes, - conn->buf, conn->in_ptr - conn->buf, conn->ptr - conn->buf); + conn->err, conn->status, conn->base.got_bytes, conn->base.total_bytes, + conn->base.buf, conn->base.in_ptr - conn->base.buf, conn->base.ptr - conn->base.buf); // Dump buffer contents as a hexdump - for (offs = 0, left = conn->total_bytes, p = conn->buf; p < conn->in_ptr;) + for (offs = 0, left = conn->base.total_bytes, p = conn->base.buf; p < conn->base.in_ptr;) { char buf[TH_DUMP_BYTES + 1]; size_t bufoffs, amount = left < TH_DUMP_BYTES ? left : TH_DUMP_BYTES; diff -r 6624893ad528 -r 11fa2bf90251 th_network.h --- a/th_network.h Mon Jun 23 16:59:36 2014 +0300 +++ b/th_network.h Fri Jul 04 02:18:26 2014 +0300 @@ -85,20 +85,8 @@ }; -typedef struct _th_conn_t +typedef struct _th_base_conn_t { - // Proxy settings and data - struct - { - char *host; - struct hostent *hst; - int type, auth_type; - int port; - struct in_addr addr; - char *userid, *passwd; - int mode, addr_type; - } proxy; - // Target host data char *host; struct hostent *hst; @@ -109,17 +97,35 @@ struct in_addr addr; fd_set sockfds; + // Data buffer + char *buf, *ptr, *in_ptr; + ssize_t bufsize, got_bytes, total_bytes; + +} th_base_conn_t; + + +typedef struct _th_conn_t +{ + // Connection + th_base_conn_t base; + + // Proxy settings and data + struct + { + th_base_conn_t conn; + int type, auth_type; + int mode, addr_type; + char *userid, *passwd; + } proxy; + + // Status + int err; + int status; + // Error handling and status message functors void (*errfunc)(struct _th_conn_t *conn, int err, const char *msg); void (*msgfunc)(struct _th_conn_t *conn, int loglevel, const char *msg); - int err; - int status; - - // Data buffer - char *buf, *ptr, *in_ptr; - ssize_t bufsize, got_bytes, total_bytes; - void *node; } th_conn_t; @@ -140,6 +146,7 @@ int th_conn_set_proxy_mode(th_conn_t *conn, const int mode); int th_conn_set_proxy_addr_type(th_conn_t *conn, const int atype); int th_conn_set_proxy_auth_user(th_conn_t *conn, const char *userid, const char *passwd); + int th_conn_open(th_conn_t *conn, const int port, const char *host); int th_conn_close(th_conn_t *); void th_conn_free(th_conn_t *);