diff --git a/man/3proxy.cfg.5 b/man/3proxy.cfg.5 index ffcca9a..1aefc3a 100644 --- a/man/3proxy.cfg.5 +++ b/man/3proxy.cfg.5 @@ -448,6 +448,7 @@ shutdown. Sets the delimiter character used to separate username from hostname in proxy authentication strings (e.g. for FTP, POP3 proxies). Default is \'@\'. For example, to use \'#\' instead: delimchar #. This allows usernames to contain the \'@\' character. +Applies to the services started after it. .br .BR archiver @@ -506,7 +507,7 @@ RADIUS authentication, which serve all the services, use the values given last. .br Sets TCP maximum segment size (MSS) for outgoing connections. This can be used to work around path MTU discovery issues or to optimize traffic for specific -network conditions. +network conditions. Applies to the services started after it. .br .BR radius @@ -1101,6 +1102,7 @@ than being sent without a parent. Number of attempts to reach a parent proxy. Default is 2. Each attempt picks a parent again, leaving out the ones which already failed, so this is also the number of different parents a request may be tried through. +Applies to the services started after it. .br @@ -1473,7 +1475,7 @@ data filtering will be performed through filtering plugins to avoid data corruption and/or Content-Length changing. A body up to this size is read whole into memory and filtered at once. 0 removes the limit, but then a body is only filtered whole if it fits in the connection's 16K buffer. -Default is 1MB (1048576). +Default is 1MB (1048576). Applies to the services started after it. .SH SSL/TLS SUPPORT SSL/TLS support is built into 3proxy (since 0.9.7) when compiled with OpenSSL diff --git a/src/acl.c b/src/acl.c index d094754..fec2b46 100644 --- a/src/acl.c +++ b/src/acl.c @@ -383,7 +383,7 @@ int checkACL(struct clientparam * param){ if((param->operation == UDPASSOC)? (param->ctrlsocksrv != INVALID_SOCKET) : (param->remsock != INVALID_SOCKET)) { return 0; } - for(; i < conf.parentretries; i++){ + for(; i < param->srv->parentretries; i++){ dup = *acentry; res = handleredirect(param, &dup); if(!res) break; diff --git a/src/common.c b/src/common.c index 2c8ce21..a4e6757 100644 --- a/src/common.c +++ b/src/common.c @@ -670,15 +670,15 @@ int parseusername(char *username, struct clientparam *param, int extpasswd){ int parseconnusername(char *username, struct clientparam *param, int extpasswd, uint16_t port){ char *sb, *se; if(!username || !*username) return 1; - if ((sb=strchr(username, conf.delimchar)) == NULL){ + if ((sb=strchr(username, param->srv->delimchar)) == NULL){ if(!*param->hostname && param->remsock == INVALID_SOCKET) return 2; if(*param->hostname)parsehostname((char *)param->hostname, param, *SAPORT(¶m->req)? ntohs(*SAPORT(¶m->req)) : port); return parseusername(username, param, extpasswd); } - while ((se=strchr(sb+1, conf.delimchar)))sb=se; + while ((se=strchr(sb+1, param->srv->delimchar)))sb=se; *(sb) = 0; if(parseusername(username, param, extpasswd)) return 3; - *(sb) = conf.delimchar; + *(sb) = param->srv->delimchar; if(parsehostname(sb+1, param, *SAPORT(¶m->req)? ntohs(*SAPORT(¶m->req)) : port)) return 4; return 0; } @@ -803,7 +803,7 @@ int doconnect(struct clientparam * param){ param->sinsl = param->srv->extsa; } *SAPORT(¶m->sinsl) = 0; - setopts(param->remsock, ¶m->srv->srvsockopts); + setopts(param->remsock, ¶m->srv->srvsockopts, param->srv->maxseg); #ifndef _WIN32 /* not on Windows, see the accepting side in proxymain.c */ diff --git a/src/proxy.c b/src/proxy.c index d243e4c..5f17ee8 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -180,7 +180,7 @@ static int growbuf(unsigned char **buf, int *bufsize, int need){ with no limit set a body is only read whole if it fits the buffer. Returns how much is there, less than len if the body did not all come. */ static uint64_t fillwhole(struct clientparam *param, DIRECTION which, uint64_t len){ - if(conf.filtermaxsize && bufroom(param, which, (unsigned long)len)) return 0; + if(param->srv->filtermaxsize && bufroom(param, which, (unsigned long)len)) return 0; return sockfillbuf(param, which, (unsigned long)len, CONNECTION_S); } #endif @@ -727,7 +727,7 @@ for(;;){ if(action != PASS) RETURN(19); } - if (conf.filtermaxsize && contentlength64 > (uint64_t)conf.filtermaxsize) { + if (param->srv->filtermaxsize && contentlength64 > (uint64_t)param->srv->filtermaxsize) { param->nolongdatfilter = 1; } else if(param->ndatfilterscli > 0 && contentlength64 > 0 && contentlength64 == (uint64_t)(unsigned long)contentlength64){ @@ -1228,7 +1228,7 @@ for(;;){ param->nolongdatfilter = 0; - if (conf.filtermaxsize && contentlength64 > (uint64_t)conf.filtermaxsize) { + if (param->srv->filtermaxsize && contentlength64 > (uint64_t)param->srv->filtermaxsize) { param->nolongdatfilter = 1; } else if(param->ndatfilterssrv > 0 && contentlength64 > 0 && contentlength64 == (uint64_t)(unsigned long)contentlength64 && param->operation != HTTP_HEAD && res != 204 && res != 304){ diff --git a/src/proxy.h b/src/proxy.h index 18e1cf4..6be4219 100644 --- a/src/proxy.h +++ b/src/proxy.h @@ -513,7 +513,7 @@ extern struct socketoptions { char * optname; } sockopts[]; int getopts(const char *s, struct sockoptset *opts); -void setopts(SOCKET s, const struct sockoptset *opts); +void setopts(SOCKET s, const struct sockoptset *opts, int maxseg); char * printopts(char *sep); #ifdef _WINCE diff --git a/src/proxymain.c b/src/proxymain.c index 203ebff..301d625 100644 --- a/src/proxymain.c +++ b/src/proxymain.c @@ -342,7 +342,7 @@ int getopts(const char *s, struct sockoptset *opts){ return 0; } -void setopts(SOCKET s, const struct sockoptset *opts){ +void setopts(SOCKET s, const struct sockoptset *opts, int maxseg){ int i, value; for(i = 0; sockopts[i].optname && i < MAXSOCKOPTS; i++){ @@ -350,7 +350,7 @@ void setopts(SOCKET s, const struct sockoptset *opts){ value = opts->value[i]; #ifdef TCP_MAXSEG if(sockopts[i].opt == TCP_MAXSEG && *sockopts[i].optname == 'T'){ - if(!value) value = conf.maxseg; + if(!value) value = maxseg; if(!value) continue; } #endif @@ -880,7 +880,7 @@ static int srvlisten(struct srvstart *s){ perror("socket()"); return -2; } - setopts(sock, &srv->lissockopts); + setopts(sock, &srv->lissockopts, srv->maxseg); #ifdef _WIN32 ioctlsocket(sock, FIONBIO, &ul); #else @@ -940,7 +940,7 @@ static int cblisten(struct srvstart *s){ dolog(defparam, (unsigned char *)"Failed to allocate connect back socket"); return -6; } - setopts(srv->cbsock, &srv->cbssockopts); + setopts(srv->cbsock, &srv->cbssockopts, srv->maxseg); if(srv->so._bind(srv->so.state, srv->cbsock, (struct sockaddr*)&cbsa, SASIZE(&cbsa))==-1) { dolog(defparam, (unsigned char *)"Failed to bind connect back socket"); @@ -981,7 +981,7 @@ static int tcpnext(struct srvstart *s, SOCKET *client, int *nlog){ usleep(SLEEPTIME); return NEXT_RETRY; } - setopts(new_sock, &srv->cbcsockopts); + setopts(new_sock, &srv->cbcsockopts, srv->maxseg); parsehost(srv->family, s->cbc_string, (struct sockaddr *)&defparam->sincr); #if defined SO_BINDTODEVICE || defined IP_BOUND_IF @@ -1051,7 +1051,7 @@ static int tcpnext(struct srvstart *s, SOCKET *client, int *nlog){ } return NEXT_RETRY; } - setopts(new_sock, &srv->clisockopts); + setopts(new_sock, &srv->clisockopts, srv->maxseg); } size = sizeof(defparam->sincl); if(srv->so._getsockname(srv->so.state, new_sock, (struct sockaddr *)&defparam->sincl, &size)){ @@ -1478,6 +1478,10 @@ void srvinit(struct srvparam * srv, struct clientparam *param){ srv->backlog = conf.backlog; srv->stacksize = conf.stacksize; memcpy(srv->timeouts, conf.timeouts, sizeof(srv->timeouts)); + srv->filtermaxsize = conf.filtermaxsize; + srv->parentretries = conf.parentretries; + srv->maxseg = conf.maxseg; + srv->delimchar = conf.delimchar; srv->time_start = time(NULL); if(havelog && conf.logtarget){ srv->logtarget = (unsigned char *)strdup((char *)conf.logtarget); diff --git a/src/socks.c b/src/socks.c index 2b4f607..8937bb4 100644 --- a/src/socks.c +++ b/src/socks.c @@ -180,7 +180,7 @@ void * sockschild(struct clientparam* param) { param->operation = command == 2?BIND:UDPASSOC; if(command == 2){ if ((param->remsock=nssocket(param->srv, ¶m->srv->so, param->sostate, NS_OUT, SASOCK(¶m->req), SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {RETURN (11);} - setopts(param->remsock, ¶m->srv->lissockopts); + setopts(param->remsock, ¶m->srv->lissockopts, param->srv->maxseg); if(extbindtodevice(param, param->remsock)) {RETURN (12);} } break; diff --git a/src/ssl.c b/src/ssl.c index f578ba8..1ed12b4 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -297,7 +297,7 @@ SSL_CONN ssl_handshake_to_server(SOCKET s, char * hostname, SSL_CONFIG *config, fds[0].events = POLLOUT; } else break; - if(sso._poll(sso.state, fds, 1, pl->conf->timeouts[CONNECT_TO]*1000) <= 0 || !(fds[0].revents & (POLLOUT|POLLIN))) break; + if(sso._poll(sso.state, fds, 1, config->timeout*1000) <= 0 || !(fds[0].revents & (POLLOUT|POLLIN))) break; } while (err == -1); if ( err != 1 ) { @@ -372,7 +372,7 @@ SSL_CONN ssl_handshake_to_client(SOCKET s, SSL_CONFIG *config, X509 *server_cert fds[0].events = POLLOUT; } else break; - if(sso._poll(sso.state, fds, 1, pl->conf->timeouts[CONNECT_TO]*1000) <= 0 || !(fds[0].revents & (POLLOUT|POLLIN))) break; + if(sso._poll(sso.state, fds, 1, config->timeout*1000) <= 0 || !(fds[0].revents & (POLLOUT|POLLIN))) break; } while (err == -1); @@ -589,6 +589,7 @@ static void* ssl_filter_open(void * idata, struct srvparam * srv){ sc->server_min_proto_version = server_min_proto_version; sc->server_max_proto_version = server_max_proto_version; sc->client_mode = client_mode; + sc->timeout = srv->timeouts[CONNECT_TO]; sc->client_verify = client_verify; sc->server_verify = server_verify; if(client_ciphersuites) sc->client_ciphersuites = strdup(client_ciphersuites); diff --git a/src/ssl.h b/src/ssl.h index a824190..59fe580 100644 --- a/src/ssl.h +++ b/src/ssl.h @@ -52,6 +52,7 @@ struct ssl_config { int client_verify; int server_verify; int client_mode; + int timeout; /* seconds a handshake step may wait: the service's CONNECT_TO */ }; typedef struct ssl_config SSL_CONFIG; diff --git a/src/structures.h b/src/structures.h index 9140b05..50e580b 100644 --- a/src/structures.h +++ b/src/structures.h @@ -622,6 +622,8 @@ struct srvparam { int family; int stacksize; int timeouts[12]; /* conf.timeouts as they were when the service started */ + int filtermaxsize, parentretries, maxseg; /* and these */ + char delimchar; int noforce; int anonymous; struct sockoptset clisockopts, srvsockopts, lissockopts, cbcsockopts, cbssockopts;