mirror of
https://github.com/3proxy/3proxy.git
synced 2026-10-28 22:05:48 +08:00
Socket functions: _poll becomes _prepoll, which never waits
A layer over the sockets, TLS or a plugin's, no longer waits itself. Its _prepoll only tells what it knows without asking the system: the fds it knows to be ready, data TLS has already decrypted, or, returning 0, that the sockets have to be polled, for events it may rewrite: a TLS read waiting for its socket to be writable. The wait is sockpoll()'s, which calls _prepoll first and then polls, so that a wait can be made other than with poll() in one place: a client of an event loop is to wait in the loop. Whatever a rewritten wait gets is given to the caller as what it asked for, its chance to try again, and the events it asked for are given back. With no fds sockpoll() sleeps, which WSAPoll() would refuse. TLS remembers what a read or a write it could not do waits for. A read needing to write, or a write to read, was an error which ended the connection, as when TLS 1.3 answers a key update while the socket cannot take more; it now waits for what TLS needs, as one needing what it was asked for always did. Incompatible for plugins, which have to be built again with the same version of 3proxy, the structures they share not kept compatible: - struct sockfuncs has _prepoll(state, fds, nfds) in place of _poll(state, fds, nfds, timeout). A plugin replacing _poll replaces _prepoll: it must not wait, returns the number of fds it set revents of (events then left as they are), 0 for the fds to be polled (with events as it leaves them, revents left to the poll) or -1, and calls the _prepoll it replaced when it has nothing to say itself. - Waiting for sockets is sockpoll(sf, state, fds, nfds, timeout), not so._poll() of the socket functions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
718798c7fc
commit
b4bbcb9e9a
@ -560,7 +560,7 @@ int radsend(struct clientparam * param, int auth, int stop){
|
||||
memset(fds, 0, sizeof(fds));
|
||||
fds[0].fd = remsock;
|
||||
fds[0].events = POLLIN;
|
||||
if(so._poll(so.state, fds, 1, param->srv->config->timeouts[SINGLEBYTE_L]*1000) <= 0) {
|
||||
if(sockpoll(&so, so.state, fds, 1, param->srv->config->timeouts[SINGLEBYTE_L]*1000) <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
61
src/common.c
61
src/common.c
@ -360,16 +360,8 @@ int
|
||||
int WINAPI def_setsockopt(void* state, SOCKET s, int level, int optname, const char *optval, int optlen){
|
||||
return setsockopt(s, level, optname, optval, optlen);
|
||||
}
|
||||
int WINAPI def_poll(void* state, struct pollfd *fds, unsigned int nfds, int timeout){
|
||||
#ifndef WITH_POLL
|
||||
#ifndef WITH_WSAPOLL
|
||||
return mypoll(fds, nfds, timeout);
|
||||
#else
|
||||
return WSAPoll(fds, nfds, timeout);
|
||||
#endif
|
||||
#else
|
||||
return poll(fds, nfds, timeout);
|
||||
#endif
|
||||
int WINAPI def_prepoll(void* state, struct pollfd *fds, unsigned int nfds){
|
||||
return 0;
|
||||
}
|
||||
int WINAPI def_send(void* state, SOCKET s, const char *msg, int len, int flags){
|
||||
return send(s, msg, len, flags);
|
||||
@ -419,12 +411,8 @@ int
|
||||
return setsockopt(s, level, optname, optval, optlen);
|
||||
}
|
||||
|
||||
int def_poll(void* state, struct pollfd *fds, nfds_t nfds, int timeout){
|
||||
#ifndef WITH_POLL
|
||||
return mypoll(fds, nfds, timeout);
|
||||
#else
|
||||
return poll(fds, nfds, timeout);
|
||||
#endif
|
||||
int def_prepoll(void* state, struct pollfd *fds, nfds_t nfds){
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* a peer gone is an error of the send, not SIGPIPE, where the system can
|
||||
@ -466,7 +454,7 @@ struct sockfuncs so = {
|
||||
def_getsockname,
|
||||
def_getsockopt,
|
||||
def_setsockopt,
|
||||
def_poll,
|
||||
def_prepoll,
|
||||
def_send,
|
||||
def_sendto,
|
||||
def_recv,
|
||||
@ -475,6 +463,43 @@ struct sockfuncs so = {
|
||||
def_closesocket
|
||||
};
|
||||
|
||||
/* Waits as poll() does for fds of sockets made with sf, once their layers
|
||||
know of nothing ready already. A layer may have a socket waited for
|
||||
other than as asked, a TLS read for it to be writable: whatever it gets
|
||||
is then the caller's chance to try again, revents what the caller asked
|
||||
for, and events are given back as they were. With no fds it only
|
||||
sleeps. */
|
||||
#define POLLFAIL (POLLERR|POLLHUP|POLLNVAL)
|
||||
int sockpoll(struct sockfuncs *sf, void *state, struct pollfd *fds, unsigned nfds, int timeout){
|
||||
short own[64], *events = own;
|
||||
unsigned i;
|
||||
int res;
|
||||
|
||||
if(!nfds){
|
||||
if(timeout > 0) usleep(timeout * SLEEPTIME);
|
||||
return 0;
|
||||
}
|
||||
if(nfds > sizeof(own)/sizeof(own[0]) && !(events = malloc(nfds * sizeof(*events)))) return -1;
|
||||
for(i = 0; i < nfds; i++) events[i] = fds[i].events;
|
||||
if(!(res = sf->_prepoll(state, fds, nfds))){
|
||||
#ifndef WITH_POLL
|
||||
#ifndef WITH_WSAPOLL
|
||||
res = mypoll(fds, nfds, timeout);
|
||||
#else
|
||||
res = WSAPoll(fds, nfds, timeout);
|
||||
#endif
|
||||
#else
|
||||
res = poll(fds, (nfds_t)nfds, timeout);
|
||||
#endif
|
||||
for(i = 0; res > 0 && i < nfds; i++)
|
||||
if(fds[i].events != events[i] && (fds[i].revents & ~POLLFAIL))
|
||||
fds[i].revents = events[i] | (fds[i].revents & POLLFAIL);
|
||||
}
|
||||
for(i = 0; i < nfds; i++) fds[i].events = events[i];
|
||||
if(events != own) free(events);
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef _WINCE
|
||||
|
||||
static char cebuf[1024];
|
||||
@ -664,7 +689,7 @@ int connectwithpoll(struct clientparam *param, SOCKET sock, struct sockaddr *sa,
|
||||
memset(fds, 0, sizeof(fds));
|
||||
fds[0].fd = sock;
|
||||
fds[0].events = POLLOUT;
|
||||
if((param?param->srv->so._poll(param->sostate, fds, 1, to*1000):so._poll(so.state, fds, 1, to*1000)) <= 0 || !(fds[0].revents & POLLOUT) || (fds[0].revents & (POLLERR|POLLHUP))) {
|
||||
if((param?sockpoll(¶m->srv->so, param->sostate, fds, 1, to*1000):sockpoll(&so, so.state, fds, 1, to*1000)) <= 0 || !(fds[0].revents & POLLOUT) || (fds[0].revents & (POLLERR|POLLHUP))) {
|
||||
return 13;
|
||||
}
|
||||
return 0;
|
||||
|
||||
@ -222,7 +222,7 @@ void * ftpprchild(struct clientparam* param) {
|
||||
fds.fd = clidatasock;
|
||||
fds.events = POLLIN;
|
||||
|
||||
res = param->srv->so._poll (param->sostate, &fds, 1, param->srv->timeouts[STRING_L]*1000);
|
||||
res = sockpoll(¶m->srv->so, param->sostate, &fds, 1, param->srv->timeouts[STRING_L]*1000);
|
||||
if(res != 1) {
|
||||
RETURN(857);
|
||||
}
|
||||
|
||||
@ -1190,7 +1190,7 @@ static void httpsrv_linger(struct clientparam *param)
|
||||
memset(&fd, 0, sizeof(fd));
|
||||
fd.fd = param->clisock;
|
||||
fd.events = POLLIN;
|
||||
if(param->srv->so._poll(param->sostate, &fd, 1, timeo * 1000) <= 0) break;
|
||||
if(sockpoll(¶m->srv->so, param->sostate, &fd, 1, timeo * 1000) <= 0) break;
|
||||
got = (int)param->srv->so._recv(param->sostate, param->clisock, buf,
|
||||
(left > HTTPSRV_BLOCK)? (int)HTTPSRV_BLOCK : (int)left, 0);
|
||||
if(got <= 0) break;
|
||||
@ -1225,7 +1225,7 @@ static int proxypass(struct clientparam *param, struct httpreq *r)
|
||||
memset(&fd, 0, sizeof(fd));
|
||||
fd.fd = param->remsock;
|
||||
fd.events = POLLIN;
|
||||
if(param->srv->so._poll(param->sostate, &fd, 1, 0) > 0
|
||||
if(sockpoll(¶m->srv->so, param->sostate, &fd, 1, 0) > 0
|
||||
&& (fd.revents & (POLLIN|POLLHUP|POLLERR|POLLNVAL))){
|
||||
/* anything arriving now belongs to no request */
|
||||
stale = 1;
|
||||
|
||||
@ -47,7 +47,7 @@ static void serveparam(struct clientparam *param){
|
||||
fds.events = POLLIN;
|
||||
fds.revents = 0;
|
||||
for(i=5+(param->srv->maxchild>>10); i; i--){
|
||||
if(param->srv->so._poll(param->sostate, &fds, 1, 1000*CONNBACK_TO)!=1){
|
||||
if(sockpoll(¶m->srv->so, param->sostate, &fds, 1, 1000*CONNBACK_TO)!=1){
|
||||
dolog(param, (unsigned char *)"Connect back not received, check connback client");
|
||||
i = 0;
|
||||
break;
|
||||
@ -86,7 +86,7 @@ static void serveparam(struct clientparam *param){
|
||||
rf.fd = param->remsock;
|
||||
rf.events = POLLIN;
|
||||
rf.revents = 0;
|
||||
if(param->srv->so._poll(param->sostate, &rf, 1, 0) == 1){
|
||||
if(sockpoll(¶m->srv->so, param->sostate, &rf, 1, 0) == 1){
|
||||
param->srv->so._closesocket(param->sostate, param->remsock);
|
||||
param->remsock = INVALID_SOCKET;
|
||||
if(skips > 0){ skips--; i++; }
|
||||
|
||||
@ -210,7 +210,7 @@ static int tcploop(struct srvstart *s, int *haveslot){
|
||||
}
|
||||
if (connectback) break;
|
||||
if (srv->config->paused != srv->paused) break;
|
||||
error = srv->so._poll(srv->so.state, &srv->fds, 1, 1000);
|
||||
error = sockpoll(&srv->so, srv->so.state, &srv->fds, 1, 1000);
|
||||
if (error >= 1) break;
|
||||
if (error == 0) continue;
|
||||
if (errno != EAGAIN && errno != EINTR) {
|
||||
|
||||
@ -638,7 +638,7 @@ static int udploop(struct srvstart *s){
|
||||
st.of[nfds++] = ss;
|
||||
}
|
||||
}
|
||||
n = srv->so._poll(srv->so.state, st.fds, nfds, timeo);
|
||||
n = sockpoll(&srv->so, srv->so.state, st.fds, nfds, timeo);
|
||||
if(n < 0 && errno != EINTR && errno != EAGAIN){
|
||||
res = 91;
|
||||
break;
|
||||
|
||||
@ -411,9 +411,9 @@ static int copyfdtosock(struct fp_stream * fps, DIRECTION which, long len){
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static int WINAPI fp_poll(void *state, struct pollfd *fds, unsigned int nfds, int timeout){
|
||||
static int WINAPI fp_prepoll(void *state, struct pollfd *fds, unsigned int nfds){
|
||||
#else
|
||||
static int fp_poll(void *state, struct pollfd *fds, nfds_t nfds, int timeout){
|
||||
static int fp_prepoll(void *state, struct pollfd *fds, nfds_t nfds){
|
||||
#endif
|
||||
struct fp_stream *fps = NULL;
|
||||
int res;
|
||||
@ -458,7 +458,7 @@ static int fp_poll(void *state, struct pollfd *fds, nfds_t nfds, int timeout){
|
||||
}
|
||||
|
||||
}
|
||||
return sso._poll(sso.state, fds, nfds, timeout);
|
||||
return sso._prepoll(sso.state, fds, nfds);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
@ -916,7 +916,7 @@ static int file_loaded=0;
|
||||
file_loaded = 1;
|
||||
pl = pluginlink;
|
||||
memcpy(&sso, pl->so, sizeof(struct sockfuncs));
|
||||
pl->so->_poll = fp_poll;
|
||||
pl->so->_prepoll = fp_prepoll;
|
||||
pl->so->_send = fp_send;
|
||||
pl->so->_sendto = fp_sendto;
|
||||
pl->so->_recv = fp_recv;
|
||||
|
||||
@ -567,7 +567,7 @@ for(;;){
|
||||
fds[0].events = POLLIN;
|
||||
fds[1].fd = param->remsock;
|
||||
fds[1].events = POLLIN;
|
||||
res = param->srv->so._poll(param->sostate, fds, 2, param->srv->timeouts[STRING_S]*1000);
|
||||
res = sockpoll(¶m->srv->so, param->sostate, fds, 2, param->srv->timeouts[STRING_S]*1000);
|
||||
if(res<=0) {
|
||||
RETURN(555);
|
||||
}
|
||||
|
||||
@ -332,6 +332,7 @@ int nsbroken(void);
|
||||
/* a function everywhere, never a macro: its callers have preprocessor
|
||||
lines among its arguments */
|
||||
SOCKET nssocket(struct srvparam *srv, struct sockfuncs *sf, void *state, int side, int domain, int type, int protocol);
|
||||
int sockpoll(struct sockfuncs *sf, void *state, struct pollfd *fds, unsigned nfds, int timeout);
|
||||
int socksend(struct clientparam *param, SOCKET sock, unsigned char * buf, int bufsize, int to);
|
||||
int socksendto(struct clientparam *param, SOCKET sock, struct sockaddr * sin, unsigned char * buf, int bufsize, int to);
|
||||
int sockrecvfrom(struct clientparam *param, SOCKET sock, struct sockaddr * sin, unsigned char * buf, int bufsize, int to);
|
||||
|
||||
@ -23,7 +23,7 @@ int socksend(struct clientparam *param, SOCKET sock, unsigned char * buf, int bu
|
||||
continue;
|
||||
}
|
||||
if(res < 0 && errno != EAGAIN && errno != EINTR) break;
|
||||
res = param?param->srv->so._poll(param->sostate, &fds, 1, to*1000):so._poll(so.state, &fds, 1, to*1000);
|
||||
res = param?sockpoll(¶m->srv->so, param->sostate, &fds, 1, to*1000):sockpoll(&so, so.state, &fds, 1, to*1000);
|
||||
if(res < 0 && (errno == EAGAIN || errno == EINTR)) continue;
|
||||
if(res < 1) break;
|
||||
} while (sent < bufsize);
|
||||
@ -40,7 +40,7 @@ int socksendto(struct clientparam *param, SOCKET sock, struct sockaddr * sin, un
|
||||
do {
|
||||
if(timetoexit) return 0;
|
||||
fds.events = POLLOUT;
|
||||
res = param?param->srv->so._poll(param->sostate, &fds, 1, to):so._poll(so.state, &fds, 1, to);
|
||||
res = param?sockpoll(¶m->srv->so, param->sostate, &fds, 1, to):sockpoll(&so, so.state, &fds, 1, to);
|
||||
if(res < 0 && (errno == EAGAIN || errno == EINTR)) continue;
|
||||
if(res < 1) break;
|
||||
res = param?param->srv->so._sendto(param->sostate, sock, (char *)buf + sent, bufsize - sent, 0, sin, SASIZE(sin)):so._sendto(so.state, sock, (char *)buf + sent, bufsize - sent, 0, sin, SASIZE(sin));
|
||||
@ -62,7 +62,7 @@ int sockrecvfrom(struct clientparam *param, SOCKET sock, struct sockaddr * sin,
|
||||
fds.events = POLLIN;
|
||||
for(;;){
|
||||
if(timetoexit) return EOF;
|
||||
res = param?param->srv->so._poll(param->sostate, &fds, 1, to):so._poll(so.state, &fds, 1, to);
|
||||
res = param?sockpoll(¶m->srv->so, param->sostate, &fds, 1, to):sockpoll(&so, so.state, &fds, 1, to);
|
||||
if (res<1) return 0;
|
||||
sasize = sizeof(PROXYSOCKADDRTYPE);
|
||||
/* sin NULL for a stream socket: nothing to learn the address into */
|
||||
|
||||
@ -260,7 +260,7 @@ log(logbuf);
|
||||
memset(fds, 0, sizeof(fds));
|
||||
fds[0].fd = param->clisock;
|
||||
fds[1].fd = param->remsock;
|
||||
param->srv->so._poll(param->sostate, fds, 2, sleeptime);
|
||||
sockpoll(¶m->srv->so, param->sostate, fds, 2, sleeptime);
|
||||
sleeptime = 0;
|
||||
}
|
||||
if((param->srv->logdumpsrv && (param->statssrv64 > param->srv->logdumpsrv)) ||
|
||||
@ -966,7 +966,7 @@ log("ready reading from server pipe");
|
||||
#ifdef WITHLOG
|
||||
log("entering poll");
|
||||
#endif
|
||||
res = param->srv->so._poll(param->sostate, fds, fdsc,
|
||||
res = sockpoll(¶m->srv->so, param->sostate, fds, fdsc,
|
||||
((CLIENTTERMREAD || SERVERTERMREAD)?
|
||||
MIN(timeo, param->srv->timeouts[LINGER_TO]) : timeo) * 1000);
|
||||
#ifdef WITHLOG
|
||||
|
||||
@ -355,7 +355,7 @@ fflush(stderr);
|
||||
fds[0].fd = param->remsock;
|
||||
fds[1].fd = param->clisock;
|
||||
fds[0].events = fds[1].events = POLLIN;
|
||||
res = param->srv->so._poll(param->sostate, fds, 2, param->srv->timeouts[CONNECTION_L] * 1000);
|
||||
res = sockpoll(¶m->srv->so, param->sostate, fds, 2, param->srv->timeouts[CONNECTION_L] * 1000);
|
||||
if (res < 1 || fds[1].revents) {
|
||||
res = 460;
|
||||
break;
|
||||
|
||||
46
src/ssl.c
46
src/ssl.c
@ -75,6 +75,9 @@ static int ktls = 0;
|
||||
struct SSLsock {
|
||||
SOCKET s;
|
||||
SSL_CONN conn;
|
||||
/* what a read and a write which could not be done wait for, POLLIN
|
||||
or POLLOUT, 0 once one is: TLS may have to write to read */
|
||||
short rwant, wwant;
|
||||
};
|
||||
|
||||
struct SSLstate {
|
||||
@ -103,10 +106,12 @@ static void addSSL(
|
||||
if (cli_s != INVALID_SOCKET){
|
||||
SOSTATE->cli.s = cli_s;
|
||||
SOSTATE->cli.conn = cli_conn;
|
||||
SOSTATE->cli.rwant = SOSTATE->cli.wwant = 0;
|
||||
}
|
||||
if (srv_s != INVALID_SOCKET){
|
||||
SOSTATE->srv.s = srv_s;
|
||||
SOSTATE->srv.conn = srv_conn;
|
||||
SOSTATE->srv.rwant = SOSTATE->srv.wwant = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,12 +142,14 @@ static ssize_t ssl_send(void *state, SOCKET s, const void *msg, size_t len, int
|
||||
int res, err;
|
||||
if((res = ssl_write(sslq->conn, (void *)msg, len)) <= 0){
|
||||
err = SSL_get_error((SSL *)((ssl_conn*)sslq->conn)->ssl, res);
|
||||
if (err == SSL_ERROR_WANT_WRITE){
|
||||
if (err == SSL_ERROR_WANT_WRITE || err == SSL_ERROR_WANT_READ){
|
||||
sslq->wwant = (err == SSL_ERROR_WANT_READ)? POLLIN : POLLOUT;
|
||||
seterrno3(EAGAIN);
|
||||
return -1;
|
||||
}
|
||||
else seterrno3(err);
|
||||
}
|
||||
else sslq->wwant = 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -161,12 +168,14 @@ static ssize_t ssl_sendto(void *state, SOCKET s, const void *msg, size_t len, in
|
||||
int res, err;
|
||||
if((res = ssl_write(sslq->conn, (void *)msg, len)) <= 0){
|
||||
err = SSL_get_error((SSL *)((ssl_conn*)sslq->conn)->ssl, res);
|
||||
if (err == SSL_ERROR_WANT_WRITE){
|
||||
if (err == SSL_ERROR_WANT_WRITE || err == SSL_ERROR_WANT_READ){
|
||||
sslq->wwant = (err == SSL_ERROR_WANT_READ)? POLLIN : POLLOUT;
|
||||
seterrno3(EAGAIN);
|
||||
return -1;
|
||||
}
|
||||
else seterrno3(err);
|
||||
}
|
||||
else sslq->wwant = 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -184,12 +193,14 @@ static ssize_t ssl_recvfrom(void *state, SOCKET s, void *msg, size_t len, int f
|
||||
int res, err;
|
||||
if((res = ssl_read(sslq->conn, (void *)msg, len)) <= 0) {
|
||||
err = SSL_get_error((SSL *)((ssl_conn*)sslq->conn)->ssl, res);
|
||||
if (err == SSL_ERROR_WANT_READ) {
|
||||
if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
|
||||
sslq->rwant = (err == SSL_ERROR_WANT_WRITE)? POLLOUT : POLLIN;
|
||||
seterrno3(EAGAIN);
|
||||
return -1;
|
||||
}
|
||||
else seterrno3(err);
|
||||
}
|
||||
else sslq->rwant = 0;
|
||||
return res;
|
||||
}
|
||||
return sso._recvfrom(sso.state, s, msg, len, flags, from, fromlen);
|
||||
@ -206,12 +217,14 @@ static ssize_t ssl_recv(void *state, SOCKET s, void *msg, size_t len, int flags)
|
||||
int res, err;
|
||||
if((res = ssl_read(sslq->conn, (void *)msg, len)) <= 0) {
|
||||
err = SSL_get_error((SSL *)((ssl_conn*)sslq->conn)->ssl, res);
|
||||
if (err == SSL_ERROR_WANT_READ) {
|
||||
if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
|
||||
sslq->rwant = (err == SSL_ERROR_WANT_WRITE)? POLLOUT : POLLIN;
|
||||
seterrno3(EAGAIN);
|
||||
return -1;
|
||||
}
|
||||
else seterrno3(err);
|
||||
}
|
||||
else sslq->rwant = 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -228,14 +241,18 @@ static int WINAPI ssl_closesocket(void *state, SOCKET s){
|
||||
return sso._closesocket(sso.state, s);
|
||||
}
|
||||
|
||||
/* Data already decrypted makes its socket readable. A read or a write TLS
|
||||
could not do has its socket waited for as TLS needs it. */
|
||||
#ifdef _WIN32
|
||||
static int WINAPI ssl_poll(void *state, struct pollfd *fds, unsigned int nfds, int timeout){
|
||||
static int WINAPI ssl_prepoll(void *state, struct pollfd *fds, unsigned int nfds){
|
||||
#else
|
||||
static int ssl_poll(void *state, struct pollfd *fds, nfds_t nfds, int timeout){
|
||||
static int ssl_prepoll(void *state, struct pollfd *fds, nfds_t nfds){
|
||||
#endif
|
||||
struct SSLsock *sslq = NULL;
|
||||
unsigned int i;
|
||||
int ret = 0;
|
||||
short events;
|
||||
|
||||
for(i = 0; i < nfds; i++){
|
||||
if((fds[i].events & POLLIN) && (sslq = searchSSL(state, fds[i].fd)) && ssl_pending(sslq->conn)){
|
||||
fds[i].revents = POLLIN;
|
||||
@ -244,9 +261,14 @@ static int ssl_poll(void *state, struct pollfd *fds, nfds_t nfds, int timeout){
|
||||
else fds[i].revents = 0;
|
||||
}
|
||||
if(ret) return ret;
|
||||
|
||||
ret = sso._poll(state, fds, nfds, timeout);
|
||||
return ret;
|
||||
for(i = 0; i < nfds; i++){
|
||||
if(!(sslq = searchSSL(state, fds[i].fd))) continue;
|
||||
events = fds[i].events & ~(POLLIN|POLLOUT);
|
||||
if(fds[i].events & POLLIN) events |= sslq->rwant? sslq->rwant : POLLIN;
|
||||
if(fds[i].events & POLLOUT) events |= sslq->wwant? sslq->wwant : POLLOUT;
|
||||
fds[i].events = events;
|
||||
}
|
||||
return sso._prepoll(sso.state, fds, nfds);
|
||||
}
|
||||
|
||||
SSL_CONN ssl_handshake_to_server(SOCKET s, char * hostname, SSL_CONFIG *config, SSL_CERT *server_cert, char **errSSL)
|
||||
@ -298,7 +320,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, config->timeout*1000) <= 0 || !(fds[0].revents & (POLLOUT|POLLIN))) break;
|
||||
if(sockpoll(&sso, sso.state, fds, 1, config->timeout*1000) <= 0 || !(fds[0].revents & (POLLOUT|POLLIN))) break;
|
||||
} while (err == -1);
|
||||
|
||||
if ( err != 1 ) {
|
||||
@ -373,7 +395,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, config->timeout*1000) <= 0 || !(fds[0].revents & (POLLOUT|POLLIN))) break;
|
||||
if(sockpoll(&sso, sso.state, fds, 1, config->timeout*1000) <= 0 || !(fds[0].revents & (POLLOUT|POLLIN))) break;
|
||||
} while (err == -1);
|
||||
|
||||
|
||||
@ -737,7 +759,7 @@ static void* ssl_filter_open(void * idata, struct srvparam * srv){
|
||||
srv->so._recvfrom = ssl_recvfrom;
|
||||
srv->so._shutdown = ssl_shutdown;
|
||||
srv->so._closesocket = ssl_closesocket;
|
||||
srv->so._poll = ssl_poll;
|
||||
srv->so._prepoll = ssl_prepoll;
|
||||
}
|
||||
if(sc && (sc->mitm || sc->cli)){
|
||||
#if !defined(WITH_WOLFSSL) && OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
|
||||
@ -573,6 +573,14 @@ struct sockoptset {
|
||||
};
|
||||
|
||||
|
||||
/* _prepoll never waits: it tells what a layer over the socket knows to be
|
||||
ready without asking the system, data a TLS connection has already
|
||||
decrypted, and what the system is to be asked instead of what the caller
|
||||
asked, events rewritten: a TLS read waiting for its socket to be
|
||||
writable. It returns the number of fds it has set revents of, the rest
|
||||
to be ignored and events left as they are; 0 when the sockets have to be
|
||||
polled, for their events as it leaves them, revents left to the poll;
|
||||
or -1. The wait itself is sockpoll()'s, which calls it first. */
|
||||
struct sockfuncs {
|
||||
void * state;
|
||||
void (*freefunc)(void* state);
|
||||
@ -586,7 +594,7 @@ struct sockfuncs {
|
||||
int (WINAPI *_getsockname)(void* state, SOCKET s, struct sockaddr * name, int * namelen);
|
||||
int (WINAPI *_getsockopt)(void* state, SOCKET s, int level, int optname, char * optval, int * optlen);
|
||||
int (WINAPI *_setsockopt)(void* state, SOCKET s, int level, int optname, const char *optval, int optlen);
|
||||
int (WINAPI *_poll)(void* state, struct pollfd *fds, unsigned int nfds, int timeout);
|
||||
int (WINAPI *_prepoll)(void* state, struct pollfd *fds, unsigned int nfds);
|
||||
int (WINAPI *_send)(void* state, SOCKET s, const char *msg, int len, int flags);
|
||||
int (WINAPI *_sendto)(void* state, SOCKET s, const char *msg, int len, int flags, const struct sockaddr *to, int tolen);
|
||||
int (WINAPI *_recv)(void* state, SOCKET s, char *buf, int len, int flags);
|
||||
@ -603,7 +611,7 @@ struct sockfuncs {
|
||||
int (*_getsockname)(void* state, SOCKET s, struct sockaddr * name, socklen_t * namelen);
|
||||
int (*_getsockopt)(void* state, SOCKET s, int level, int optname, void * optval, socklen_t * optlen);
|
||||
int (*_setsockopt)(void* state, int s, int level, int optname, const void *optval, socklen_t optlen);
|
||||
int (*_poll)(void* state, struct pollfd *fds, nfds_t nfds, int timeout);
|
||||
int (*_prepoll)(void* state, struct pollfd *fds, nfds_t nfds);
|
||||
ssize_t (*_send)(void* state, SOCKET s, const void *msg, size_t len, int flags);
|
||||
ssize_t (*_sendto)(void* state, SOCKET s, const void *msg, size_t len, int flags, const struct sockaddr *to, SASIZETYPE tolen);
|
||||
ssize_t (*_recv)(void* state, SOCKET s, void *buf, size_t len, int flags);
|
||||
|
||||
@ -209,7 +209,7 @@ int udpsockmap(struct clientparam *param, int timeo)
|
||||
udpfds(param, &p);
|
||||
|
||||
for (;;) {
|
||||
res = param->srv->so._poll(param->sostate, p.fds, p.nfds, timeo * 1000);
|
||||
res = sockpoll(¶m->srv->so, param->sostate, p.fds, p.nfds, timeo * 1000);
|
||||
if (res < 0) return 481;
|
||||
if (res == 0) return 92;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user