From f3511f80a627dcc2c82d331e92c26fb32d8c7196 Mon Sep 17 00:00:00 2001 From: hugoc Date: Wed, 13 Dec 2023 02:22:20 +0100 Subject: [PATCH] dig works --- Makefile | 2 +- src/core.c | 367 +++++++++++++++++++++++++++++++------------ src/libproxychains.c | 206 ++++++++++++++++++++++-- 3 files changed, 458 insertions(+), 117 deletions(-) diff --git a/Makefile b/Makefile index 3320904..23ba476 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ LOBJS = src/version.o \ GENH = src/version.h -CFLAGS += -Wall -O0 -g -std=c99 -D_GNU_SOURCE -pipe +CFLAGS += -Wall -O0 -g -std=c99 -D_GNU_SOURCE -pipe -DDEBUG NO_AS_NEEDED = -Wl,--no-as-needed LDFLAGS = -fPIC $(NO_AS_NEEDED) $(LIBDL) $(PTHREAD) INC = diff --git a/src/core.c b/src/core.c index 39d3362..9d566c0 100644 --- a/src/core.c +++ b/src/core.c @@ -674,6 +674,23 @@ size_t write_buf_to_iov(void* buff, size_t buff_len, struct iovec* iov, size_t i return written; } + +size_t write_iov_to_buf(void* buff, size_t buff_len, struct iovec* iov, size_t iov_len){ + + size_t written = 0; + int i = 0; + size_t min = 0; + //size_t iov_total_len = get_iov_total_len(iov, iov_len); + + while( (written < buff_len) && (i < iov_len)){ + min = ((buff_len-written)atyp == ATYP_V6) && !memcmp(addr->addr.v6, "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12)){ PDEBUG("casting v4inv6 address to v4 address\n"); @@ -723,6 +740,7 @@ int is_from_chain_head(udp_relay_chain chain, struct sockaddr src_addr){ } + int decapsulate_check_udp_packet(void* in_buffer, size_t in_buffer_len, udp_relay_chain chain, socks5_addr* src_addr, unsigned short* src_port, void* udp_data, size_t* udp_data_len){ PFUNC(); @@ -787,7 +805,7 @@ int decapsulate_check_udp_packet(void* in_buffer, size_t in_buffer_len, udp_rela return 0; } -int unsocks_udp_packet(void* in_buffer, size_t in_buffer_len, udp_relay_chain chain, ip_type* src_ip, unsigned short* src_port, void* udp_data, size_t* udp_data_len){ +int unsocksify_udp_packet(void* in_buffer, size_t in_buffer_len, udp_relay_chain chain, ip_type* src_ip, unsigned short* src_port, void* udp_data, size_t* udp_data_len){ PFUNC(); // Decapsulate all the UDP headers and check that the packet came from the right proxy nodes int rc; @@ -863,7 +881,7 @@ int receive_udp_packet(int sockfd, udp_relay_chain chain, ip_type* src_ip, unsig int rc; size_t udp_data_len = data_len; - rc = unsocks_udp_packet(buffer, bytes_received, chain, src_ip, src_port, data, &udp_data_len); + rc = unsocksify_udp_packet(buffer, bytes_received, chain, src_ip, src_port, data, &udp_data_len); if(rc != SUCCESS){ PDEBUG("error unSOCKSing the UDP packet\n"); return -1; @@ -914,8 +932,45 @@ int receive_udp_packet(int sockfd, udp_relay_chain chain, ip_type* src_ip, unsig // return udp_data_len; } -int send_udp_packet(int sockfd, udp_relay_chain chain, ip_type target_ip, unsigned short target_port, char frag, char * data, unsigned int data_len) { +int encapsulate_udp_packet(udp_relay_chain chain, socks5_addr dst_addr, unsigned short dst_port, void* buffer, size_t* buffer_len){ + PFUNC(); + + unsigned int written = 0; + unsigned int offset = 0; + udp_relay_node * tmp = chain.head; + + while ((tmp->next != NULL) && (written < *buffer_len)) + { + socks5_addr tmpaddr; + tmpaddr.atyp = (tmp->next)->bnd_addr.is_v6?ATYP_V6:ATYP_V4; + memcpy(tmpaddr.addr.v6, (tmp->next)->bnd_addr.addr.v6, (tmp->next)->bnd_addr.is_v6?16:4); + + written = write_udp_header(tmpaddr, (tmp->next)->bnd_port, 0, buffer+offset, *buffer_len - offset); + if (written == -1){ + PDEBUG("error write_udp_header\n"); + return -1; + } + offset += written; + + tmp = tmp->next; + } + + written = write_udp_header(dst_addr, dst_port, 0, buffer+offset, *buffer_len-offset); + if (written == -1){ + PDEBUG("error write_udp_header\n"); + return -1; + } + offset += written; + + *buffer_len = offset; + + return 0; +} + +int socksify_udp_packet(void* udp_data, size_t udp_data_len, udp_relay_chain chain, ip_type dst_ip, unsigned short dst_port, void* buffer, size_t* buffer_len){ + + PFUNC(); if (chain.head == NULL ){ PDEBUG("provided chain is empty\n"); return -1; @@ -924,119 +979,68 @@ int send_udp_packet(int sockfd, udp_relay_chain chain, ip_type target_ip, unsign char *dns_name = NULL; char hostnamebuf[MSG_LEN_MAX]; size_t dns_len = 0; - socks5_addr target_addr; + socks5_addr dst_addr; // we use ip addresses with 224.* to lookup their dns name in our table, to allow remote DNS resolution // the range 224-255.* is reserved, and it won't go outside (unless the app does some other stuff with // the results returned from gethostbyname et al.) // the hardcoded number 224 can now be changed using the config option remote_dns_subnet to i.e. 127 - if(!target_ip.is_v6 && proxychains_resolver >= DNSLF_RDNS_START && target_ip.addr.v4.octet[0] == remote_dns_subnet) { - target_addr.atyp = ATYP_DOM; - dns_len = rdns_get_host_for_ip(target_ip.addr.v4, target_addr.addr.dom.name); + if(!dst_ip.is_v6 && proxychains_resolver >= DNSLF_RDNS_START && dst_ip.addr.v4.octet[0] == remote_dns_subnet) { + dst_addr.atyp = ATYP_DOM; + dns_len = rdns_get_host_for_ip(dst_ip.addr.v4, dst_addr.addr.dom.name); PDEBUG("dnslen: %d\n", dns_len); - if(!dns_len) goto err; - else dns_name = target_addr.addr.dom.name; - target_addr.addr.dom.len = dns_len & 0xFF; - PDEBUG("dnslen in struct: %d\n", target_addr.addr.dom.len); + if(!dns_len) return -1; + else dns_name = dst_addr.addr.dom.name; + dst_addr.addr.dom.len = dns_len & 0xFF; + PDEBUG("dnslen in struct: %d\n", dst_addr.addr.dom.len); } else { - if(target_ip.is_v6){ - target_addr.atyp = ATYP_V6; - memcpy(target_addr.addr.v6, target_ip.addr.v6, 16); + if(dst_ip.is_v6){ + dst_addr.atyp = ATYP_V6; + memcpy(dst_addr.addr.v6, dst_ip.addr.v6, 16); } else { - target_addr.atyp = ATYP_V4; - memcpy(target_addr.addr.v4.octet, target_ip.addr.v4.octet, 4); + dst_addr.atyp = ATYP_V4; + memcpy(dst_addr.addr.v4.octet, dst_ip.addr.v4.octet, 4); } } PDEBUG("host dns %s\n", dns_name ? dns_name : ""); + + // Write all the UDP headers into the provided buffer + int rc; + size_t tmp_buffer_len = *buffer_len; + rc = encapsulate_udp_packet(chain, dst_addr, dst_port, buffer, &tmp_buffer_len); + if(rc != SUCCESS){ + PDEBUG("error encapsulate_udp_packet()\n"); + return -1; + + } + + + // Append UDP data in the remaining space of the buffer + int min = (udp_data_len>(buffer_len-tmp_buffer_len))?(buffer_len-tmp_buffer_len):udp_data_len; + memcpy(buffer + tmp_buffer_len, udp_data, min); + + *buffer_len = tmp_buffer_len + min; + + return 0; + +} + +int send_udp_packet(int sockfd, udp_relay_chain chain, ip_type target_ip, unsigned short target_port, char frag, char * data, unsigned int data_len) { + PFUNC(); + char send_buffer[65535]; + size_t send_buffer_len = sizeof(send_buffer); + int rc; - // Allocate a new buffer for the packet data and all the headers - unsigned int headers_size = 0; - udp_relay_node * tmp = chain.head; - int len = 0; - while(tmp->next != NULL){ - - // switch ((tmp->next)->bnd_addr.atyp) - // { - // case ATYP_V4: - // len = 4; - // break; - // case ATYP_V6: - // len = 6; - // break; - // case ATYP_DOM: - // len = (tmp->next)->bnd_addr.addr.dom.len + 1; - // break; - // default: - // break; - // } - - len = (tmp->next)->bnd_addr.is_v6?16:4; - - headers_size += len + 6; - tmp = tmp->next; - } - - switch (target_addr.atyp) - { - case ATYP_V4: - len = 4; - break; - case ATYP_V6: - len = 6; - break; - case ATYP_DOM: - len = target_addr.addr.dom.len + 1; - break; - default: - break; - } - - headers_size += len + 6; - - char * buff = NULL; - if (NULL == (buff = (char*)malloc(headers_size+data_len))){ - PDEBUG("error malloc buffer\n"); + rc = socksify_udp_packet(data, data_len, chain, target_ip, target_port,send_buffer, &send_buffer_len); + if(rc != SUCCESS){ + PDEBUG("error socksify_udp_packet()\n"); return -1; } - - // Append each header to the buffer - - unsigned int written = 0; - unsigned int offset = 0; - - tmp = chain.head; - while (tmp->next != NULL) - { - - socks5_addr tmpaddr; - tmpaddr.atyp = (tmp->next)->bnd_addr.is_v6?ATYP_V6:ATYP_V4; - memcpy(tmpaddr.addr.v6, (tmp->next)->bnd_addr.addr.v6, (tmp->next)->bnd_addr.is_v6?16:4); - - written = write_udp_header(tmpaddr, (tmp->next)->bnd_port, 0, buff+offset, headers_size + data_len - offset); - if (written == -1){ - PDEBUG("error write_udp_header\n"); - goto err; - } - offset += written; - - tmp = tmp->next; - } - - written = write_udp_header(target_addr, target_port, 0, buff + offset, headers_size + data_len - offset); - if (written == -1){ - PDEBUG("error write_udp_header\n"); - goto err; - } - offset += written; - - // Append data to the buffer - memcpy(buff + offset, data, data_len); - // Send the packet // FIXME: should write_n_bytes be used here instead ? @@ -1059,20 +1063,175 @@ int send_udp_packet(int sockfd, udp_relay_chain chain, ip_type target_ip, unsign int sent = 0; - sent = true_sendto(sockfd, buff, offset+data_len, 0, (struct sockaddr *) (v6?(void*)&addr6:(void*)&addr), v6?sizeof(addr6):sizeof(addr) ); - if (sent != offset+data_len){ + sent = true_sendto(sockfd, send_buffer, send_buffer_len, 0, (struct sockaddr *) (v6?(void*)&addr6:(void*)&addr), v6?sizeof(addr6):sizeof(addr) ); + if (sent != send_buffer_len){ PDEBUG("true_sendto error\n"); - goto err; + return -1; } return SUCCESS; - err: - free(buff); - return -1; +} + +// int send_udp_packet(int sockfd, udp_relay_chain chain, ip_type target_ip, unsigned short target_port, char frag, char * data, unsigned int data_len) { + +// if (chain.head == NULL ){ +// PDEBUG("provided chain is empty\n"); +// return -1; +// } + +// char *dns_name = NULL; +// char hostnamebuf[MSG_LEN_MAX]; +// size_t dns_len = 0; +// socks5_addr target_addr; +// // we use ip addresses with 224.* to lookup their dns name in our table, to allow remote DNS resolution +// // the range 224-255.* is reserved, and it won't go outside (unless the app does some other stuff with +// // the results returned from gethostbyname et al.) +// // the hardcoded number 224 can now be changed using the config option remote_dns_subnet to i.e. 127 +// if(!target_ip.is_v6 && proxychains_resolver >= DNSLF_RDNS_START && target_ip.addr.v4.octet[0] == remote_dns_subnet) { +// target_addr.atyp = ATYP_DOM; +// dns_len = rdns_get_host_for_ip(target_ip.addr.v4, target_addr.addr.dom.name); +// PDEBUG("dnslen: %d\n", dns_len); +// if(!dns_len) goto err; +// else dns_name = target_addr.addr.dom.name; +// target_addr.addr.dom.len = dns_len & 0xFF; +// PDEBUG("dnslen in struct: %d\n", target_addr.addr.dom.len); + +// } else { +// if(target_ip.is_v6){ +// target_addr.atyp = ATYP_V6; +// memcpy(target_addr.addr.v6, target_ip.addr.v6, 16); + +// } else { +// target_addr.atyp = ATYP_V4; +// memcpy(target_addr.addr.v4.octet, target_ip.addr.v4.octet, 4); +// } +// } + +// PDEBUG("host dns %s\n", dns_name ? dns_name : ""); + -} +// // Allocate a new buffer for the packet data and all the headers +// unsigned int headers_size = 0; +// udp_relay_node * tmp = chain.head; +// int len = 0; +// while(tmp->next != NULL){ + +// // switch ((tmp->next)->bnd_addr.atyp) +// // { +// // case ATYP_V4: +// // len = 4; +// // break; +// // case ATYP_V6: +// // len = 6; +// // break; +// // case ATYP_DOM: +// // len = (tmp->next)->bnd_addr.addr.dom.len + 1; +// // break; +// // default: +// // break; +// // } + +// len = (tmp->next)->bnd_addr.is_v6?16:4; + +// headers_size += len + 6; +// tmp = tmp->next; +// } + +// switch (target_addr.atyp) +// { +// case ATYP_V4: +// len = 4; +// break; +// case ATYP_V6: +// len = 6; +// break; +// case ATYP_DOM: +// len = target_addr.addr.dom.len + 1; +// break; +// default: +// break; +// } + +// headers_size += len + 6; + +// char * buff = NULL; +// if (NULL == (buff = (char*)malloc(headers_size+data_len))){ +// PDEBUG("error malloc buffer\n"); +// return -1; +// } + + +// // Append each header to the buffer + +// unsigned int written = 0; +// unsigned int offset = 0; + +// tmp = chain.head; +// while (tmp->next != NULL) +// { + +// socks5_addr tmpaddr; +// tmpaddr.atyp = (tmp->next)->bnd_addr.is_v6?ATYP_V6:ATYP_V4; +// memcpy(tmpaddr.addr.v6, (tmp->next)->bnd_addr.addr.v6, (tmp->next)->bnd_addr.is_v6?16:4); + +// written = write_udp_header(tmpaddr, (tmp->next)->bnd_port, 0, buff+offset, headers_size + data_len - offset); +// if (written == -1){ +// PDEBUG("error write_udp_header\n"); +// goto err; +// } +// offset += written; + +// tmp = tmp->next; +// } + +// written = write_udp_header(target_addr, target_port, 0, buff + offset, headers_size + data_len - offset); +// if (written == -1){ +// PDEBUG("error write_udp_header\n"); +// goto err; +// } +// offset += written; + +// // Append data to the buffer +// memcpy(buff + offset, data, data_len); + +// // Send the packet +// // FIXME: should write_n_bytes be used here instead ? + +// // if(chain.head->bnd_addr.atyp == ATYP_DOM){ +// // PDEBUG("BND_ADDR of type DOMAINE (0x03) not supported yet\n"); +// // goto err; +// // } +// int v6 = chain.head->bnd_addr.is_v6 == ATYP_V6; + +// struct sockaddr_in addr = { +// .sin_family = AF_INET, +// .sin_port = chain.head->bnd_port, +// .sin_addr.s_addr = (in_addr_t) chain.head->bnd_addr.addr.v4.as_int, +// }; +// struct sockaddr_in6 addr6 = { +// .sin6_family = AF_INET6, +// .sin6_port = chain.head->bnd_port, +// }; +// if(v6) memcpy(&addr6.sin6_addr.s6_addr, chain.head->bnd_addr.addr.v6, 16); + +// int sent = 0; + +// sent = true_sendto(sockfd, buff, offset+data_len, 0, (struct sockaddr *) (v6?(void*)&addr6:(void*)&addr), v6?sizeof(addr6):sizeof(addr) ); +// if (sent != offset+data_len){ +// PDEBUG("true_sendto error\n"); +// goto err; +// } + +// return SUCCESS; + +// err: +// free(buff); +// return -1; + + +// } #define TP " ... " diff --git a/src/libproxychains.c b/src/libproxychains.c index 1cf39b4..812dc1e 100644 --- a/src/libproxychains.c +++ b/src/libproxychains.c @@ -1021,6 +1021,7 @@ HOOKFUNC(ssize_t, sendto, int sockfd, const void *buf, size_t len, int flags, DUMP_RELAY_CHAINS_LIST(relay_chains); memcpy(dest_ip.addr.v6, v6 ? (void*)p_addr_in6 : (void*)p_addr_in, v6?16:4); + //TODO: is it better to do 'return send_udp_packet' ? if (SUCCESS != send_udp_packet(sockfd, *relay_chain, dest_ip, htons(port),0, buf, len)){ PDEBUG("could not send udp packet\n"); errno = ECONNREFUSED; @@ -1031,10 +1032,188 @@ HOOKFUNC(ssize_t, sendto, int sockfd, const void *buf, size_t len, int flags, return SUCCESS; } -// HOOKFUNC(ssize_t, sendmsg, int sockfd, const struct msghdr *msg, int flags){ -// //TODO hugoc -// return 0; -// } +HOOKFUNC(ssize_t, sendmsg, int sockfd, const struct msghdr *msg, int flags){ + INIT(); + PFUNC(); + + //TODO : do we keep this FASTOPEN code from sendto() ? + // if (flags & MSG_FASTOPEN) { + // if (!connect(sockfd, dest_addr, addrlen) && errno != EINPROGRESS) { + // return -1; + // } + // dest_addr = NULL; + // addrlen = 0; + // flags &= ~MSG_FASTOPEN; + + // return true_sendto(sockfd, buf, len, flags, dest_addr, addrlen); + // } + + //TODO hugoc: case of SOCK_DGRAM with AF_INET or AF_INET6 + struct sockaddr* dest_addr; + dest_addr = msg->msg_name; + socklen_t addrlen = msg->msg_namelen; + + DEBUGDECL(char str[256]); + int socktype = 0, ret = 0; + socklen_t optlen = 0; + optlen = sizeof(socktype); + sa_family_t fam = SOCKFAMILY(*dest_addr); + getsockopt(sockfd, SOL_SOCKET, SO_TYPE, &socktype, &optlen); + if(!((fam == AF_INET || fam == AF_INET6) && socktype == SOCK_DGRAM)){ + return true_sendmsg(sockfd, msg, flags); + } + + PDEBUG("before send dump : "); + DUMP_BUFFER(msg->msg_name, msg->msg_namelen); + + ip_type dest_ip; + struct in_addr *p_addr_in; + struct in6_addr *p_addr_in6; + dnat_arg *dnat = NULL; + size_t i; + int remote_dns_connect = 0; + unsigned short port; + int v6 = dest_ip.is_v6 = fam == AF_INET6; + + p_addr_in = &((struct sockaddr_in *) dest_addr)->sin_addr; + p_addr_in6 = &((struct + sockaddr_in6 *) dest_addr)->sin6_addr; + port = !v6 ? ntohs(((struct sockaddr_in *) dest_addr)->sin_port) + : ntohs(((struct sockaddr_in6 *) dest_addr)->sin6_port); + struct in_addr v4inv6; + if(v6 && is_v4inv6(p_addr_in6)) { + memcpy(&v4inv6.s_addr, &p_addr_in6->s6_addr[12], 4); + v6 = dest_ip.is_v6 = 0; + p_addr_in = &v4inv6; + } + if(!v6 && !memcmp(p_addr_in, "\0\0\0\0", 4)) { + errno = ECONNREFUSED; + return -1; + } + + PDEBUG("target: %s\n", inet_ntop(v6 ? AF_INET6 : AF_INET, v6 ? (void*)p_addr_in6 : (void*)p_addr_in, str, sizeof(str))); + PDEBUG("port: %d\n", port); + PDEBUG("client socket: %d\n", sockfd); + + // check if connect called from proxydns + remote_dns_connect = !v6 && (ntohl(p_addr_in->s_addr) >> 24 == remote_dns_subnet); + + // more specific first + if (!v6) for(i = 0; i < num_dnats && !remote_dns_connect && !dnat; i++) + if(dnats[i].orig_dst.s_addr == p_addr_in->s_addr) + if(dnats[i].orig_port && (dnats[i].orig_port == port)) + dnat = &dnats[i]; + + if (!v6) for(i = 0; i < num_dnats && !remote_dns_connect && !dnat; i++) + if(dnats[i].orig_dst.s_addr == p_addr_in->s_addr) + if(!dnats[i].orig_port) + dnat = &dnats[i]; + + if (dnat) { + p_addr_in = &dnat->new_dst; + if (dnat->new_port) + port = dnat->new_port; + } + + for(i = 0; i < num_localnet_addr && !remote_dns_connect; i++) { + if (localnet_addr[i].port && localnet_addr[i].port != port) + continue; + if (localnet_addr[i].family != (v6 ? AF_INET6 : AF_INET)) + continue; + if (v6) { + size_t prefix_bytes = localnet_addr[i].in6_prefix / CHAR_BIT; + size_t prefix_bits = localnet_addr[i].in6_prefix % CHAR_BIT; + if (prefix_bytes && memcmp(p_addr_in6->s6_addr, localnet_addr[i].in6_addr.s6_addr, prefix_bytes) != 0) + continue; + if (prefix_bits && (p_addr_in6->s6_addr[prefix_bytes] ^ localnet_addr[i].in6_addr.s6_addr[prefix_bytes]) >> (CHAR_BIT - prefix_bits)) + continue; + } else { + if((p_addr_in->s_addr ^ localnet_addr[i].in_addr.s_addr) & localnet_addr[i].in_mask.s_addr) + continue; + } + PDEBUG("accessing localnet using true_sendmsg\n"); + return true_sendmsg(sockfd, msg, flags); + } + + // Check if a chain of UDP relay is already opened for this socket + udp_relay_chain* relay_chain = get_relay_chain(relay_chains, sockfd); + if(relay_chain == NULL){ + // No chain is opened for this socket, open one + PDEBUG("opening new chain of relays for %d\n", sockfd); + if(NULL == (relay_chain = open_relay_chain(proxychains_pd, proxychains_proxy_count, proxychains_ct, proxychains_max_chain))){ + PDEBUG("could not open a chain of relay\n"); + errno = ECONNREFUSED; + return -1; + } + relay_chain->sockfd = sockfd; + add_relay_chain(&relay_chains, relay_chain); + } + DUMP_RELAY_CHAINS_LIST(relay_chains); + + memcpy(dest_ip.addr.v6, v6 ? (void*)p_addr_in6 : (void*)p_addr_in, v6?16:4); + + + // Allocate buffer for header creation + char send_buffer[65535]; //TODO maybe we can do better about size ? + size_t send_buffer_len = sizeof(send_buffer); + + //Move iovec udp data contained in msg to one buffer + char udp_data[65535]; + size_t udp_data_len = sizeof(udp_data); + udp_data_len = write_iov_to_buf(udp_data, udp_data_len, msg->msg_iov, msg->msg_iovlen); + + // Exec socksify_udp_packet + int rc; + rc = socksify_udp_packet(udp_data, udp_data_len, *relay_chain, dest_ip, htons(port),send_buffer, &send_buffer_len); + if(rc != SUCCESS){ + PDEBUG("error socksify_udp_packet()\n"); + return -1; + } + + + // send with true_sendmsg() + //prepare our msg + struct iovec iov[1]; + iov[0].iov_base = send_buffer; + iov[0].iov_len = send_buffer_len; + + + struct msghdr tmp_msg; + tmp_msg.msg_control = msg->msg_control; + tmp_msg.msg_controllen = msg->msg_controllen; + tmp_msg.msg_flags = msg->msg_flags; + tmp_msg.msg_iov = iov; + tmp_msg.msg_iovlen = 1; + + v6 = relay_chain->head->bnd_addr.is_v6 == ATYP_V6; + struct sockaddr_in addr = { + .sin_family = AF_INET, + .sin_port = relay_chain->head->bnd_port, + .sin_addr.s_addr = (in_addr_t) relay_chain->head->bnd_addr.addr.v4.as_int, + }; + struct sockaddr_in6 addr6 = { + .sin6_family = AF_INET6, + .sin6_port = relay_chain->head->bnd_port, + }; + if(v6) memcpy(&addr6.sin6_addr.s6_addr, relay_chain->head->bnd_addr.addr.v6, 16); + + + + tmp_msg.msg_name = (struct sockaddr*)(v6?(void*)&addr6:(void*)&addr); + tmp_msg.msg_namelen = v6?sizeof(addr6):sizeof(addr) ; + + + //send it + + int sent = 0; + sent = true_sendmsg(sockfd, &tmp_msg, flags); + if(-1 == sent){ + PDEBUG("error true_sendmsg\n"); + return -1; + } + PDEBUG("Successfully sent UDP packet with true_sendmsg()\n"); + return sent; +} HOOKFUNC(ssize_t, recvmsg, int sockfd, struct msghdr *msg, int flags){ @@ -1100,7 +1279,7 @@ HOOKFUNC(ssize_t, recvmsg, int sockfd, struct msghdr *msg, int flags){ PDEBUG("exec true_recvmsg\n"); bytes_received = true_recvmsg(sockfd, &tmp_msg, flags); if(-1 == bytes_received){ - PDEBUG("true_recvmsg returned -1\n"); + PDEBUG("true_recvmsg returned -1, errno: %d, %s\n", errno,strerror(errno)); return -1; } @@ -1112,8 +1291,9 @@ HOOKFUNC(ssize_t, recvmsg, int sockfd, struct msghdr *msg, int flags){ PDEBUG("successful recvmsg(), %d bytes received\n", bytes_received); //Check that the packet was received from the first relay of the chain - - if(!is_from_chain_head(*relay_chain, *(struct sockaddr *)(msg->msg_name))){ + DUMP_BUFFER(tmp_msg.msg_name, tmp_msg.msg_namelen); + DUMP_BUFFER(relay_chain->head->bnd_addr.addr.v4.octet, 4); + if(!is_from_chain_head(*relay_chain, *(struct sockaddr *)(tmp_msg.msg_name))){ PDEBUG("UDP packet not received from the proxy chain's head, transfering it as is\n"); // Write the data we received in tmp_msg to msg int written = write_buf_to_iov(buffer, bytes_received, msg->msg_iov, msg->msg_iovlen); @@ -1137,7 +1317,7 @@ HOOKFUNC(ssize_t, recvmsg, int sockfd, struct msghdr *msg, int flags){ char udp_data[65535]; size_t udp_data_len = sizeof(udp_data); - rc = unsocks_udp_packet(buffer, bytes_received, *relay_chain, &src_ip, &src_port, udp_data, &udp_data_len); + rc = unsocksify_udp_packet(buffer, bytes_received, *relay_chain, &src_ip, &src_port, udp_data, &udp_data_len); if(rc != SUCCESS){ PDEBUG("error unSOCKSing the UDP packet\n"); return -1; @@ -1178,7 +1358,7 @@ HOOKFUNC(ssize_t, recvmsg, int sockfd, struct msghdr *msg, int flags){ src_addr_v4->sin_family = AF_INET; src_addr_v4->sin_port = src_port; memcpy(&(src_addr_v4->sin_addr.s_addr), src_ip.addr.v6+12, 4); - msg->msg_namelen = sizeof(src_addr_v4); + msg->msg_namelen = sizeof(struct sockaddr_in); } else if(src_ip.is_v6){ PDEBUG("src_ip is true v6\n"); @@ -1190,7 +1370,7 @@ HOOKFUNC(ssize_t, recvmsg, int sockfd, struct msghdr *msg, int flags){ src_addr_v6->sin6_family = AF_INET6; src_addr_v6->sin6_port = src_port; memcpy(src_addr_v6->sin6_addr.s6_addr, src_ip.addr.v6, 16); - msg->msg_namelen = sizeof(src_addr_v6); + msg->msg_namelen = sizeof(struct sockaddr_in6); }else { if(msg->msg_namelen < sizeof(struct sockaddr_in)){ PDEBUG("addrlen too short for ipv4\n"); @@ -1199,9 +1379,11 @@ HOOKFUNC(ssize_t, recvmsg, int sockfd, struct msghdr *msg, int flags){ src_addr_v4->sin_family = AF_INET; src_addr_v4->sin_port = src_port; src_addr_v4->sin_addr.s_addr = (in_addr_t) src_ip.addr.v4.as_int; - msg->msg_namelen = sizeof(src_addr_v4); + msg->msg_namelen = sizeof(struct sockaddr_in); } } + PDEBUG("after recv dump : "); + DUMP_BUFFER(msg->msg_name, msg->msg_namelen); return udp_data_len; @@ -1382,7 +1564,7 @@ static void setup_hooks(void) { SETUP_SYM(sendto); SETUP_SYM(recvfrom); SETUP_SYM(recvmsg); - //SETUP_SYM(sendmsg); + SETUP_SYM(sendmsg); SETUP_SYM(recv); SETUP_SYM(gethostbyname); SETUP_SYM(getaddrinfo);