diff --git a/src/core.h b/src/core.h index c4dcf8f..564df20 100644 --- a/src/core.h +++ b/src/core.h @@ -95,6 +95,10 @@ typedef int (*getaddrinfo_t)(const char *, const char *, const struct addrinfo * typedef int (*getnameinfo_t) (const struct sockaddr *, socklen_t, char *, socklen_t, char *, socklen_t, int); +typedef ssize_t (*sendto_t) (int sockfd, const void *buf, size_t len, int flags, + const struct sockaddr *dest_addr, socklen_t addrlen); + + extern connect_t true_connect; extern gethostbyname_t true_gethostbyname; diff --git a/src/libproxychains.c b/src/libproxychains.c index fb5e43f..c9eaeaa 100644 --- a/src/libproxychains.c +++ b/src/libproxychains.c @@ -52,6 +52,7 @@ getaddrinfo_t true_getaddrinfo; freeaddrinfo_t true_freeaddrinfo; getnameinfo_t true_getnameinfo; gethostbyaddr_t true_gethostbyaddr; +sendto_t true_sendto; int tcp_read_time_out; int tcp_connect_time_out; @@ -113,6 +114,7 @@ static void do_init(void) { proxychains_write_log(LOG_PREFIX "DLL init: proxychains-ng %s\n", proxychains_get_version()); SETUP_SYM(connect); + SETUP_SYM(sendto); SETUP_SYM(gethostbyname); SETUP_SYM(getaddrinfo); SETUP_SYM(freeaddrinfo); @@ -479,3 +481,20 @@ struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type) { } return NULL; } + +#ifndef MSG_FASTOPEN +# define MSG_FASTOPEN 0x20000000 +#endif + +ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, + const struct sockaddr *dest_addr, socklen_t addrlen) { + 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); +} diff --git a/tests/test_sendto.c b/tests/test_sendto.c new file mode 100644 index 000000000..57b008f --- /dev/null +++ b/tests/test_sendto.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef MSG_FASTOPEN +# define MSG_FASTOPEN 0x20000000 +#endif + +void error(const char *msg) +{ + perror(msg); + exit(1); +} + +int main(int argc, char *argv[]) +{ + if (argc < 4) { + printf("Usage: %s host port method(connect or sendto)\n", argv[0]); + return 1; + } + const char *hostname = argv[1]; + const int portno = atoi(argv[2]); + const char *method = argv[3]; + char request[BUFSIZ]; + sprintf(request, "GET / HTTP/1.0\r\nHost: %s\r\n\r\n", hostname); + int sockfd, n; + struct sockaddr_in serv_addr; + struct hostent *server; + + char buffer[BUFSIZ]; + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd < 0) error("ERROR opening socket"); + server = gethostbyname(hostname); + if (server == NULL) { + fprintf(stderr, "%s: no such host\n", hostname); + return 1; + } + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + memcpy(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length); + serv_addr.sin_port = htons(portno); + if (!strcmp(method, "connect")) { + if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) + error("connect"); + n = send(sockfd, request, strlen(request), 0); + } else if (!strcmp(method, "sendto")) { + n = sendto(sockfd, request, strlen(request), MSG_FASTOPEN, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); + } else { + printf("Unknown method %s\n", method); + return 1; + } + if (n < 0) + error("send"); + memset(buffer, 0, BUFSIZ); + n = read(sockfd, buffer, BUFSIZ - 1); + if (n < 0) + error("ERROR reading from socket"); + printf("%s\n", buffer); + close(sockfd); + return 0; +}