mirror of
https://github.com/moparisthebest/curl
synced 2024-12-22 16:18:48 -05:00
sws.c: some IPv6 proxy mode peparatory adjustments
This commit is contained in:
parent
52824ed1ab
commit
812fa73057
@ -53,7 +53,8 @@ sockfilt_CFLAGS = $(AM_CFLAGS)
|
|||||||
|
|
||||||
sws_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(USEFUL) $(UTIL) \
|
sws_SOURCES = $(CURLX_SRCS) $(CURLX_HDRS) $(USEFUL) $(UTIL) \
|
||||||
server_sockaddr.h \
|
server_sockaddr.h \
|
||||||
sws.c
|
sws.c \
|
||||||
|
$(top_srcdir)/lib/inet_pton.c
|
||||||
sws_LDADD = @TEST_SERVER_LIBS@
|
sws_LDADD = @TEST_SERVER_LIBS@
|
||||||
sws_CFLAGS = $(AM_CFLAGS)
|
sws_CFLAGS = $(AM_CFLAGS)
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@
|
|||||||
versions instead */
|
versions instead */
|
||||||
#include "curlx.h" /* from the private lib dir */
|
#include "curlx.h" /* from the private lib dir */
|
||||||
#include "getpart.h"
|
#include "getpart.h"
|
||||||
|
#include "inet_pton.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "server_sockaddr.h"
|
#include "server_sockaddr.h"
|
||||||
|
|
||||||
@ -119,7 +120,7 @@ struct httprequest {
|
|||||||
int prot_version; /* HTTP version * 10 */
|
int prot_version; /* HTTP version * 10 */
|
||||||
bool pipelining; /* true if request is pipelined */
|
bool pipelining; /* true if request is pipelined */
|
||||||
int callcount; /* times ProcessRequest() gets called */
|
int callcount; /* times ProcessRequest() gets called */
|
||||||
int connect_port; /* the port number CONNECT used */
|
unsigned short connect_port; /* the port number CONNECT used */
|
||||||
};
|
};
|
||||||
|
|
||||||
static int ProcessRequest(struct httprequest *req);
|
static int ProcessRequest(struct httprequest *req);
|
||||||
@ -483,21 +484,37 @@ static int ProcessRequest(struct httprequest *req)
|
|||||||
else {
|
else {
|
||||||
if(sscanf(req->reqbuf, "CONNECT %" MAXDOCNAMELEN_TXT "s HTTP/%d.%d",
|
if(sscanf(req->reqbuf, "CONNECT %" MAXDOCNAMELEN_TXT "s HTTP/%d.%d",
|
||||||
doc, &prot_major, &prot_minor) == 3) {
|
doc, &prot_major, &prot_minor) == 3) {
|
||||||
char *portp;
|
char *portp = NULL;
|
||||||
|
|
||||||
sprintf(logbuf, "Received a CONNECT %s HTTP/%d.%d request",
|
sprintf(logbuf, "Received a CONNECT %s HTTP/%d.%d request",
|
||||||
doc, prot_major, prot_minor);
|
doc, prot_major, prot_minor);
|
||||||
logmsg("%s", logbuf);
|
logmsg("%s", logbuf);
|
||||||
|
|
||||||
portp = strchr(doc, ':');
|
|
||||||
if(portp && (*(portp+1) != '\0') && ISDIGIT(*(portp+1)))
|
|
||||||
req->connect_port = strtol(portp+1, NULL, 10);
|
|
||||||
else
|
|
||||||
req->connect_port = 0;
|
|
||||||
|
|
||||||
if(req->prot_version == 10)
|
if(req->prot_version == 10)
|
||||||
req->open = FALSE; /* HTTP 1.0 closes connection by default */
|
req->open = FALSE; /* HTTP 1.0 closes connection by default */
|
||||||
|
|
||||||
|
if(doc[0] == '[') {
|
||||||
|
char *p = &doc[1];
|
||||||
|
while(*p && (ISXDIGIT(*p) || (*p == ':') || (*p == '.')))
|
||||||
|
p++;
|
||||||
|
if(*p != ']')
|
||||||
|
logmsg("Invalid CONNECT IPv6 address format");
|
||||||
|
else if (*(p+1) != ':')
|
||||||
|
logmsg("Invalid CONNECT IPv6 port format");
|
||||||
|
else
|
||||||
|
portp = p+1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
portp = strchr(doc, ':');
|
||||||
|
|
||||||
|
if(portp && (*(portp+1) != '\0') && ISDIGIT(*(portp+1))) {
|
||||||
|
unsigned long ulnum = strtoul(portp+1, NULL, 10);
|
||||||
|
if(!ulnum || (ulnum > 65535UL))
|
||||||
|
logmsg("Invalid CONNECT port received");
|
||||||
|
else
|
||||||
|
req->connect_port = curlx_ultous(ulnum);
|
||||||
|
}
|
||||||
|
|
||||||
if(!strncmp(doc, "bad", 3))
|
if(!strncmp(doc, "bad", 3))
|
||||||
/* if the host name starts with bad, we fake an error here */
|
/* if the host name starts with bad, we fake an error here */
|
||||||
req->testno = DOCNUMBER_BADCONNECT;
|
req->testno = DOCNUMBER_BADCONNECT;
|
||||||
@ -506,7 +523,7 @@ static int ProcessRequest(struct httprequest *req)
|
|||||||
CONNECT line will be used as test number! */
|
CONNECT line will be used as test number! */
|
||||||
req->testno = req->connect_port?req->connect_port:DOCNUMBER_CONNECT;
|
req->testno = req->connect_port?req->connect_port:DOCNUMBER_CONNECT;
|
||||||
else
|
else
|
||||||
req->testno = DOCNUMBER_CONNECT;
|
req->testno = req->connect_port?DOCNUMBER_CONNECT:DOCNUMBER_BADCONNECT;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
logmsg("Did not find test number in PATH");
|
logmsg("Did not find test number in PATH");
|
||||||
@ -1157,43 +1174,93 @@ static int send_doc(curl_socket_t sock, struct httprequest *req)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static curl_socket_t connect_to(const char *ipaddr, int port)
|
static curl_socket_t connect_to(const char *ipaddr, unsigned short port)
|
||||||
{
|
{
|
||||||
int flag;
|
srvr_sockaddr_union_t serveraddr;
|
||||||
struct sockaddr_in sin;
|
|
||||||
curl_socket_t serverfd;
|
curl_socket_t serverfd;
|
||||||
unsigned long hostaddr;
|
int error;
|
||||||
|
int rc;
|
||||||
hostaddr = inet_addr(ipaddr);
|
const char *op_br = "";
|
||||||
|
const char *cl_br = "";
|
||||||
if(hostaddr == ( in_addr_t)-1)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
logmsg("about to connect to %s:%d", ipaddr, port);
|
|
||||||
|
|
||||||
serverfd = socket(AF_INET, SOCK_STREAM, 0);
|
|
||||||
|
|
||||||
#ifdef TCP_NODELAY
|
#ifdef TCP_NODELAY
|
||||||
/*
|
curl_socklen_t flag = 1;
|
||||||
* Disable the Nagle algorithm
|
int level = IPPROTO_TCP;
|
||||||
*/
|
#endif
|
||||||
flag = 1;
|
|
||||||
if (setsockopt(serverfd, IPPROTO_TCP, TCP_NODELAY,
|
#ifdef ENABLE_IPV6
|
||||||
(void *)&flag, sizeof(flag)) == -1) {
|
if(use_ipv6) {
|
||||||
logmsg("====> TCP_NODELAY for server conection failed");
|
op_br = "[";
|
||||||
|
cl_br = "]";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sin.sin_family = AF_INET;
|
if(!ipaddr)
|
||||||
sin.sin_port = htons((short)port);
|
return CURL_SOCKET_BAD;
|
||||||
sin.sin_addr.s_addr = hostaddr;
|
|
||||||
if (connect(serverfd, (struct sockaddr*)(&sin),
|
logmsg("about to connect to %s%s%s:%hu",
|
||||||
sizeof(struct sockaddr_in)) != 0) {
|
op_br, ipaddr, cl_br, port);
|
||||||
fprintf(stderr, "failed to connect!\n");
|
|
||||||
return -1;
|
#ifdef ENABLE_IPV6
|
||||||
|
if(!use_ipv6)
|
||||||
|
#endif
|
||||||
|
serverfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
else
|
||||||
|
serverfd = socket(AF_INET6, SOCK_STREAM, 0);
|
||||||
|
#endif
|
||||||
|
if(CURL_SOCKET_BAD == serverfd) {
|
||||||
|
error = SOCKERRNO;
|
||||||
|
logmsg("Error creating socket for server conection: (%d) %s",
|
||||||
|
error, strerror(error));
|
||||||
|
return CURL_SOCKET_BAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
logmsg("connected fine to %s:%d, now tunnel!", ipaddr, port);
|
#ifdef TCP_NODELAY
|
||||||
|
/* Disable the Nagle algorithm */
|
||||||
|
if(setsockopt(serverfd, level, TCP_NODELAY, (void *)&flag, sizeof(flag)) < 0)
|
||||||
|
logmsg("====> TCP_NODELAY for server conection failed");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
if(!use_ipv6) {
|
||||||
|
#endif
|
||||||
|
memset(&serveraddr.sa4, 0, sizeof(serveraddr.sa4));
|
||||||
|
serveraddr.sa4.sin_family = AF_INET;
|
||||||
|
serveraddr.sa4.sin_port = htons(port);
|
||||||
|
serveraddr.sa4.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
if(Curl_inet_pton(AF_INET, ipaddr, &serveraddr.sa4.sin_addr) < 1) {
|
||||||
|
logmsg("Error inet_pton failed AF_INET conversion of '%s'", ipaddr);
|
||||||
|
sclose(serverfd);
|
||||||
|
return CURL_SOCKET_BAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = connect(serverfd, &serveraddr.sa, sizeof(serveraddr.sa4));
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memset(&serveraddr.sa6, 0, sizeof(serveraddr.sa6));
|
||||||
|
serveraddr.sa6.sin6_family = AF_INET6;
|
||||||
|
serveraddr.sa6.sin6_port = htons(port);
|
||||||
|
if(Curl_inet_pton(AF_INET6, ipaddr, &serveraddr.sa6.sin6_addr) < 1) {
|
||||||
|
logmsg("Error inet_pton failed AF_INET6 conversion of '%s'", ipaddr);
|
||||||
|
sclose(serverfd);
|
||||||
|
return CURL_SOCKET_BAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = connect(serverfd, &serveraddr.sa, sizeof(me.sa6));
|
||||||
|
}
|
||||||
|
#endif /* ENABLE_IPV6 */
|
||||||
|
|
||||||
|
if(rc) {
|
||||||
|
error = SOCKERRNO;
|
||||||
|
logmsg("Error connecting to server port %hu: (%d) %s",
|
||||||
|
port, error, strerror(error));
|
||||||
|
sclose(serverfd);
|
||||||
|
return CURL_SOCKET_BAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
logmsg("connected fine to %s%s%s:%hu, now tunnel",
|
||||||
|
op_br, ipaddr, cl_br, port);
|
||||||
|
|
||||||
return serverfd;
|
return serverfd;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user