Skip to content

Commit

Permalink
replace select by poll
Browse files Browse the repository at this point in the history
  • Loading branch information
Fabian Mauchle committed Mar 22, 2018
1 parent 3d41674 commit 408151a
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 57 deletions.
1 change: 1 addition & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Changes between 1.6.9 and the master branch
still enables code known to be buggy.
- Replace several server status bits with a single state enum.
(RADSECPROXY-71)
- Use poll instead of select to allow > 1000 concurrent connections.

Bug fixes:
- Detect the presence of docbook2x-man correctly.
Expand Down
19 changes: 6 additions & 13 deletions dtls.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#endif
#include <sys/time.h>
#include <sys/types.h>
#include <sys/select.h>
#include <poll.h>
#include <ctype.h>
#include <sys/wait.h>
#include <arpa/inet.h>
Expand Down Expand Up @@ -444,8 +444,8 @@ void *udpdtlsserverrd(void *arg) {
struct sockaddr_storage from;
socklen_t fromlen = sizeof(from);
struct dtlsservernewparams *params;
fd_set readfds;
struct timeval timeout, lastexpiry;
struct pollfd fds[1];
struct timeval lastexpiry;
pthread_t dtlsserverth;
struct hash *sessioncache;
struct sessioncacheentry *cacheentry;
Expand All @@ -456,11 +456,9 @@ void *udpdtlsserverrd(void *arg) {
gettimeofday(&lastexpiry, NULL);

for (;;) {
FD_ZERO(&readfds);
FD_SET(s, &readfds);
memset(&timeout, 0, sizeof(struct timeval));
timeout.tv_sec = 60;
ndesc = select(s + 1, &readfds, NULL, NULL, &timeout);
fds[0].fd = s;
fds[0].events = POLLIN;
ndesc = poll(fds, 1, 60000);
if (ndesc < 1) {
cacheexpire(sessioncache, &lastexpiry);
continue;
Expand Down Expand Up @@ -622,13 +620,8 @@ void *udpdtlsclientrd(void *arg) {
struct sockaddr_storage from;
socklen_t fromlen = sizeof(from);
struct clsrvconf *conf;
fd_set readfds;

for (;;) {
FD_ZERO(&readfds);
FD_SET(s, &readfds);
if (select(s + 1, &readfds, NULL, NULL, NULL) < 1)
continue;
cnt = recvfrom(s, buf, 4, MSG_PEEK | MSG_TRUNC, (struct sockaddr *)&from, &fromlen);
if (cnt == -1) {
debug(DBG_WARN, "udpdtlsclientrd: recv failed");
Expand Down
18 changes: 8 additions & 10 deletions tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#endif
#include <sys/time.h>
#include <sys/types.h>
#include <sys/select.h>
#include <poll.h>
#include <ctype.h>
#include <sys/wait.h>
#include <arpa/inet.h>
Expand Down Expand Up @@ -134,23 +134,21 @@ int tcpconnect(struct server *server, struct timeval *when, int timeout, char *t
/* returns 0 on timeout, -1 on error and num if ok */
int tcpreadtimeout(int s, unsigned char *buf, int num, int timeout) {
int ndesc, cnt, len;
fd_set readfds;
struct timeval timer;
struct pollfd fds[1];

if (s < 0)
return -1;
/* make socket non-blocking? */
for (len = 0; len < num; len += cnt) {
FD_ZERO(&readfds);
FD_SET(s, &readfds);
if (timeout) {
timer.tv_sec = timeout;
timer.tv_usec = 0;
}
ndesc = select(s + 1, &readfds, NULL, NULL, timeout ? &timer : NULL);
fds[0].fd = s;
fds[0].events = POLLIN;
ndesc = poll(fds, 1, timeout? timeout * 1000 : -1);
if (ndesc < 1)
return ndesc;

if (fds[0].revents & (POLLERR | POLLHUP | POLLNVAL) ) {
return -1;
}
cnt = read(s, buf + len, num - len);
if (cnt <= 0)
return -1;
Expand Down
21 changes: 9 additions & 12 deletions tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#endif
#include <sys/time.h>
#include <sys/types.h>
#include <sys/select.h>
#include <poll.h>
#include <ctype.h>
#include <sys/wait.h>
#include <arpa/inet.h>
Expand Down Expand Up @@ -168,24 +168,21 @@ int tlsconnect(struct server *server, struct timeval *when, int timeout, char *t
/* returns 0 on timeout, -1 on error and num if ok */
int sslreadtimeout(SSL *ssl, unsigned char *buf, int num, int timeout) {
int s, ndesc, cnt, len;
fd_set readfds;
struct timeval timer;
struct pollfd fds[1];

s = SSL_get_fd(ssl);
if (s < 0)
return -1;
/* make socket non-blocking? */
for (len = 0; len < num; len += cnt) {
if (SSL_pending(ssl) == 0) {
FD_ZERO(&readfds);
FD_SET(s, &readfds);
if (timeout) {
timer.tv_sec = timeout;
timer.tv_usec = 0;
}
ndesc = select(s + 1, &readfds, NULL, NULL, timeout ? &timer : NULL);
if (ndesc < 1)
return ndesc;
fds[0].fd = s;
fds[0].events = POLLIN;
ndesc = poll(fds, 1, timeout ? timeout * 1000 : -1);
if (ndesc < 1)
return ndesc;
if (fds[0].revents & (POLLERR | POLLHUP | POLLNVAL))
return -1;
}

cnt = SSL_read(ssl, buf + len, num - len);
Expand Down
1 change: 0 additions & 1 deletion tlscommon.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
#endif
#include <sys/time.h>
#include <sys/types.h>
#include <sys/select.h>
#include <ctype.h>
#include <sys/wait.h>
#include <arpa/inet.h>
Expand Down
7 changes: 1 addition & 6 deletions udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
#endif
#include <sys/time.h>
#include <sys/types.h>
#include <sys/select.h>
#include <ctype.h>
#include <sys/wait.h>
#include <arpa/inet.h>
Expand Down Expand Up @@ -137,7 +136,6 @@ unsigned char *radudpget(int s, struct client **client, struct server **server,
socklen_t fromlen = sizeof(from);
struct clsrvconf *p;
struct list_node *node;
fd_set readfds;
struct client *c = NULL;
struct timeval now;

Expand All @@ -146,10 +144,7 @@ unsigned char *radudpget(int s, struct client **client, struct server **server,
free(rad);
rad = NULL;
}
FD_ZERO(&readfds);
FD_SET(s, &readfds);
if (select(s + 1, &readfds, NULL, NULL, NULL) < 1)
continue;

cnt = recvfrom(s, buf, 4, MSG_PEEK | MSG_TRUNC, (struct sockaddr *)&from, &fromlen);
if (cnt == -1) {
debug(DBG_WARN, "radudpget: recv failed");
Expand Down
29 changes: 14 additions & 15 deletions util.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/select.h>
#include <poll.h>
#include <stdarg.h>
#include "debug.h"
#include "util.h"
Expand Down Expand Up @@ -177,10 +177,9 @@ int bindtoaddr(struct addrinfo *addrinfo, int family, int reuse) {
return -1;
}

int connectnonblocking(int s, const struct sockaddr *addr, socklen_t addrlen, struct timeval *timeout) {
int origflags, error = 0, r = -1;
fd_set writefds;
socklen_t len;
int connectnonblocking(int s, const struct sockaddr *addr, socklen_t addrlen, int timeout) {
int origflags, r = -1;
struct pollfd fds[1];

origflags = fcntl(s, F_GETFL, 0);
if (origflags == -1) {
Expand All @@ -198,14 +197,17 @@ int connectnonblocking(int s, const struct sockaddr *addr, socklen_t addrlen, st
if (errno != EINPROGRESS)
goto exit;

FD_ZERO(&writefds);
FD_SET(s, &writefds);
if (select(s + 1, NULL, &writefds, NULL, timeout) < 1)
fds[0].fd = s;
fds[0].events = POLLOUT;
if (poll(fds, 1, timeout * 1000) < 1)
goto exit;

len = sizeof(error);
if (!getsockopt(s, SOL_SOCKET, SO_ERROR, (char*)&error, &len) && !error)
r = 0;
if (fds[0].revents & (POLLERR | POLLHUP | POLLNVAL) ) {
debug(DBG_WARN, "Connection failed or refused");
} else if(fds[0].revents & POLLOUT) {
debug(DBG_DBG, "Connection up");
r = 0;
}

exit:
if (fcntl(s, F_SETFL, origflags) == -1)
Expand All @@ -216,14 +218,11 @@ int connectnonblocking(int s, const struct sockaddr *addr, socklen_t addrlen, st
int connecttcp(struct addrinfo *addrinfo, struct addrinfo *src, uint16_t timeout) {
int s;
struct addrinfo *res;
struct timeval to;

s = -1;
if (timeout) {
if (addrinfo && addrinfo->ai_next && timeout > 5)
timeout = 5;
to.tv_sec = timeout;
to.tv_usec = 0;
}

for (res = addrinfo; res; res = res->ai_next) {
Expand All @@ -233,7 +232,7 @@ int connecttcp(struct addrinfo *addrinfo, struct addrinfo *src, uint16_t timeout
continue;
}
if ((timeout
? connectnonblocking(s, res->ai_addr, res->ai_addrlen, &to)
? connectnonblocking(s, res->ai_addr, res->ai_addrlen, timeout)
: connect(s, res->ai_addr, res->ai_addrlen)) == 0)
break;
debug(DBG_WARN, "connecttoserver: connect failed");
Expand Down

0 comments on commit 408151a

Please sign in to comment.