mirror of
https://github.com/3proxy/3proxy.git
synced 2026-08-13 12:19:17 +08:00
Use memmove for overlapping region
This commit is contained in:
parent
a986ed7a07
commit
8c2ad56665
@ -199,6 +199,13 @@ is disabled even when built, because current Linux does not implement
|
|||||||
SPLICE_F_MOVE, so no real zero-copy takes place and the read/write path is faster
|
SPLICE_F_MOVE, so no real zero-copy takes place and the read/write path is faster
|
||||||
for most traffic. Rebuild with -DWITHSPLICE to make -s available, -s0 disables it
|
for most traffic. Rebuild with -DWITHSPLICE to make -s available, -s0 disables it
|
||||||
explicitly.
|
explicitly.
|
||||||
|
.br
|
||||||
|
.B -C
|
||||||
|
(for TCP services) keep the session until both sides close the connection
|
||||||
|
(TCP half-close). By default a connection closed by any of the sides terminates
|
||||||
|
the session, buffered data is delivered before the sockets are closed. Half-close
|
||||||
|
is required for the protocols where one of the sides closes its sending side and
|
||||||
|
expects the answer, it may cause the sockets to be kept in CLOSE_WAIT state.
|
||||||
.br
|
.br
|
||||||
(for dnspr) simple, do not use resolver and 3proxy cache, always use external DNS server.
|
(for dnspr) simple, do not use resolver and 3proxy cache, always use external DNS server.
|
||||||
.br
|
.br
|
||||||
|
|||||||
@ -329,6 +329,8 @@ int MODULEMAINFUNC (int argc, char** argv){
|
|||||||
#endif
|
#endif
|
||||||
#ifdef WITHSPLICE
|
#ifdef WITHSPLICE
|
||||||
" -s Use splice() - no filtering for data, off by default\n"
|
" -s Use splice() - no filtering for data, off by default\n"
|
||||||
|
" -C keep the session until both sides close the connection (TCP half-close),\n"
|
||||||
|
" by default connection closed by any of the sides terminates the session\n"
|
||||||
#endif
|
#endif
|
||||||
"-g(GRACE_TRAFF,GRACE_NUM,GRACE_DELAY) - delay GRACE_DELAY milliseconds before polling if average polling size below GRACE_TRAFF bytes and GRACE_NUM read operations in single directions are detected within 1 second to minimize polling\n"
|
"-g(GRACE_TRAFF,GRACE_NUM,GRACE_DELAY) - delay GRACE_DELAY milliseconds before polling if average polling size below GRACE_TRAFF bytes and GRACE_NUM read operations in single directions are detected within 1 second to minimize polling\n"
|
||||||
" -fFORMAT logging format (see documentation)\n"
|
" -fFORMAT logging format (see documentation)\n"
|
||||||
@ -596,6 +598,9 @@ int MODULEMAINFUNC (int argc, char** argv){
|
|||||||
case 'g':
|
case 'g':
|
||||||
sscanf(argv[i]+2, "%d,%d,%d", &srv.gracetraf, &srv.gracenum, &srv.gracedelay);
|
sscanf(argv[i]+2, "%d,%d,%d", &srv.gracetraf, &srv.gracenum, &srv.gracedelay);
|
||||||
break;
|
break;
|
||||||
|
case 'C':
|
||||||
|
srv.halfclose = *(argv[i]+2)? atoi(argv[i]+2) : 1;
|
||||||
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
#ifdef WITHSPLICE
|
#ifdef WITHSPLICE
|
||||||
if(isudp || srv.service == S_ADMIN)
|
if(isudp || srv.service == S_ADMIN)
|
||||||
@ -1247,6 +1252,7 @@ void srvinit(struct srvparam * srv, struct clientparam *param){
|
|||||||
#ifdef WITHSPLICE
|
#ifdef WITHSPLICE
|
||||||
srv->usesplice = 0;
|
srv->usesplice = 0;
|
||||||
#endif
|
#endif
|
||||||
|
srv->halfclose = 0;
|
||||||
memset(param, 0, sizeof(struct clientparam));
|
memset(param, 0, sizeof(struct clientparam));
|
||||||
param->srv = srv;
|
param->srv = srv;
|
||||||
param->version = srv->version;
|
param->version = srv->version;
|
||||||
|
|||||||
@ -171,12 +171,13 @@ int sockgetlinebuf(struct clientparam * param, DIRECTION which, unsigned char *
|
|||||||
if(delim != EOF){
|
if(delim != EOF){
|
||||||
unsigned char *d = (unsigned char *)memchr(base + *offp, delim, n);
|
unsigned char *d = (unsigned char *)memchr(base + *offp, delim, n);
|
||||||
if(d) n = (int)(d - (base + *offp)) + 1;
|
if(d) n = (int)(d - (base + *offp)) + 1;
|
||||||
memcpy(buf + i, base + *offp, n);
|
/* caller may use param->srvbuf / param->clibuf as buf */
|
||||||
|
memmove(buf + i, base + *offp, n);
|
||||||
i += n; *offp += n;
|
i += n; *offp += n;
|
||||||
if(d || i >= bufsize) return i;
|
if(d || i >= bufsize) return i;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
memcpy(buf + i, base + *offp, n);
|
memmove(buf + i, base + *offp, n);
|
||||||
i += n; *offp += n;
|
i += n; *offp += n;
|
||||||
if(i >= bufsize) return i;
|
if(i >= bufsize) return i;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,7 +44,13 @@ ssize_t splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t le
|
|||||||
#define MIN(a,b) ((a>b)?b:a)
|
#define MIN(a,b) ((a>b)?b:a)
|
||||||
#define RETURN(xxx) { res = xxx; goto CLEANRET; }
|
#define RETURN(xxx) { res = xxx; goto CLEANRET; }
|
||||||
|
|
||||||
|
/* Unless half-close is requested for the service, a connection closed by any
|
||||||
|
of the sides terminates the session, remaining buffered data is delivered
|
||||||
|
before the sockets are closed. */
|
||||||
|
#define SESSIONEND (!halfclose && (CLIENTTERMREAD || SERVERTERMREAD))
|
||||||
|
|
||||||
int sockmap(struct clientparam * param, int timeo, int usesplice){
|
int sockmap(struct clientparam * param, int timeo, int usesplice){
|
||||||
|
int halfclose = param->srv->halfclose;
|
||||||
uint64_t fromclient=0x7fffffffffffffff, fromserver =0x7fffffffffffffff;
|
uint64_t fromclient=0x7fffffffffffffff, fromserver =0x7fffffffffffffff;
|
||||||
uint64_t inclientbuf = 0, inserverbuf = 0;
|
uint64_t inclientbuf = 0, inserverbuf = 0;
|
||||||
int FROMCLIENT = 1, TOCLIENTBUF = 1, TOSERVER = 1,
|
int FROMCLIENT = 1, TOCLIENTBUF = 1, TOSERVER = 1,
|
||||||
@ -129,13 +135,13 @@ int sockmap(struct clientparam * param, int timeo, int usesplice){
|
|||||||
#ifdef WITHSPLICE
|
#ifdef WITHSPLICE
|
||||||
|| inserverpipe
|
|| inserverpipe
|
||||||
#endif
|
#endif
|
||||||
|| (!SERVERTERMREAD )))
|
|| (!SERVERTERMREAD && !SESSIONEND)))
|
||||||
||
|
||
|
||||||
((!SERVERTERMWRITE) && fromclient && (inclientbuf
|
((!SERVERTERMWRITE) && fromclient && (inclientbuf
|
||||||
#ifdef WITHSPLICE
|
#ifdef WITHSPLICE
|
||||||
|| inclientpipe
|
|| inclientpipe
|
||||||
#endif
|
#endif
|
||||||
|| (!CLIENTTERMREAD )))
|
|| (!CLIENTTERMREAD && !SESSIONEND)))
|
||||||
){
|
){
|
||||||
|
|
||||||
|
|
||||||
@ -354,7 +360,7 @@ log(logbuf);
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(fromclient>inclientpipe && FROMCLIENT && TOCLIENTPIPE){
|
if(fromclient>inclientpipe && FROMCLIENT && TOCLIENTPIPE && !SESSIONEND){
|
||||||
int error;
|
int error;
|
||||||
socklen_t len=sizeof(error);
|
socklen_t len=sizeof(error);
|
||||||
#ifdef WITHLOG
|
#ifdef WITHLOG
|
||||||
@ -396,7 +402,7 @@ log("done read from client to pipe");
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(fromserver > inserverpipe && FROMSERVER && TOSERVERPIPE){
|
if(fromserver > inserverpipe && FROMSERVER && TOSERVERPIPE && !SESSIONEND){
|
||||||
int error;
|
int error;
|
||||||
socklen_t len=sizeof(error);
|
socklen_t len=sizeof(error);
|
||||||
errno = 0;
|
errno = 0;
|
||||||
@ -449,7 +455,7 @@ log("done read from server to pipe\n");
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if(fromclient > inclientbuf && FROMCLIENT && TOCLIENTBUF){
|
if(fromclient > inclientbuf && FROMCLIENT && TOCLIENTBUF && !SESSIONEND){
|
||||||
#ifdef WITHLOG
|
#ifdef WITHLOG
|
||||||
log("read from client to buf");
|
log("read from client to buf");
|
||||||
#endif
|
#endif
|
||||||
@ -482,7 +488,7 @@ log("done read from client to buf");
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fromserver > inserverbuf && FROMSERVER && TOSERVERBUF){
|
if(fromserver > inserverbuf && FROMSERVER && TOSERVERBUF && !SESSIONEND){
|
||||||
#ifdef WITHLOG
|
#ifdef WITHLOG
|
||||||
log("read from server to buf");
|
log("read from server to buf");
|
||||||
#endif
|
#endif
|
||||||
@ -547,7 +553,7 @@ log("done read from server to buf");
|
|||||||
// if(!CLIENTTERMREAD || !CLIENTTERMWRITE){
|
// if(!CLIENTTERMREAD || !CLIENTTERMWRITE){
|
||||||
if(!after){
|
if(!after){
|
||||||
fds[fdsc].fd = param->clisock;
|
fds[fdsc].fd = param->clisock;
|
||||||
if(fromclient && !CLIENTTERMREAD && !FROMCLIENT && ((
|
if(fromclient && !CLIENTTERMREAD && !FROMCLIENT && !SESSIONEND && ((
|
||||||
#ifdef WITHSPLICE
|
#ifdef WITHSPLICE
|
||||||
!usesplice &&
|
!usesplice &&
|
||||||
#endif
|
#endif
|
||||||
@ -607,7 +613,7 @@ log("ready to write to client");
|
|||||||
// if(!SERVERTERMREAD || !SERVERTERMWRITE){
|
// if(!SERVERTERMREAD || !SERVERTERMWRITE){
|
||||||
if(!after){
|
if(!after){
|
||||||
fds[fdsc].fd = param->remsock;
|
fds[fdsc].fd = param->remsock;
|
||||||
if(fromserver && !SERVERTERMREAD && !FROMSERVER && ((
|
if(fromserver && !SERVERTERMREAD && !FROMSERVER && !SESSIONEND && ((
|
||||||
#ifdef WITHSPLICE
|
#ifdef WITHSPLICE
|
||||||
!usesplice &&
|
!usesplice &&
|
||||||
#endif
|
#endif
|
||||||
@ -827,3 +833,4 @@ CLEANRET:
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
#undef SESSIONEND
|
||||||
|
|||||||
@ -551,6 +551,7 @@ struct srvparam {
|
|||||||
#ifdef WITHSPLICE
|
#ifdef WITHSPLICE
|
||||||
int usesplice;
|
int usesplice;
|
||||||
#endif
|
#endif
|
||||||
|
int halfclose;
|
||||||
unsigned bufsize;
|
unsigned bufsize;
|
||||||
unsigned authcachetype, authcachetime;
|
unsigned authcachetype, authcachetime;
|
||||||
unsigned logdumpsrv, logdumpcli;
|
unsigned logdumpsrv, logdumpcli;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user