mirror of
https://github.com/3proxy/3proxy.git
synced 2026-10-16 00:25:48 +08:00
Make filtermaxsize, parentretries, delimchar and maxseg per service
Like the timeouts, each service now keeps the values given before it instead of reading the global ones while its connections run. setopts() takes the service's maxseg. The TLS handshakes wait the service's CONNECT_TO, kept in its SSL configuration, rather than the global one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
bab80ef684
commit
ca0b5e0c88
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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){
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user