aboutsummaryrefslogtreecommitdiffstats
path: root/src/libcharon/plugins/socket_default/socket_default_socket.c
diff options
context:
space:
mode:
authorMartin Willi <martin@revosec.ch>2014-11-05 16:59:39 +0100
committerMartin Willi <martin@revosec.ch>2014-11-21 12:02:07 +0100
commitce13ba62cc70fd6861ffc5e18f822cc3fb127841 (patch)
tree64f156470fa74169a76ee1827031f157b7c4d6cd /src/libcharon/plugins/socket_default/socket_default_socket.c
parent946cf367d4129635ea35254b33977f07335488ff (diff)
downloadstrongswan-ce13ba62cc70fd6861ffc5e18f822cc3fb127841.tar.bz2
strongswan-ce13ba62cc70fd6861ffc5e18f822cc3fb127841.tar.xz
socket-default: Use poll(2) instead of select
It is not only simpler, but also allows the use of arbitrary high fd numbers, which silently fails with select().
Diffstat (limited to 'src/libcharon/plugins/socket_default/socket_default_socket.c')
-rw-r--r--src/libcharon/plugins/socket_default/socket_default_socket.c66
1 files changed, 20 insertions, 46 deletions
diff --git a/src/libcharon/plugins/socket_default/socket_default_socket.c b/src/libcharon/plugins/socket_default/socket_default_socket.c
index 9cc39955b..a0e4a54c5 100644
--- a/src/libcharon/plugins/socket_default/socket_default_socket.c
+++ b/src/libcharon/plugins/socket_default/socket_default_socket.c
@@ -150,66 +150,40 @@ METHOD(socket_t, receiver, status_t,
chunk_t data;
packet_t *pkt;
host_t *source = NULL, *dest = NULL;
- int bytes_read = 0;
+ int i, bytes_read = 0, selected = -1;
bool oldstate;
-
- fd_set rfds;
- int max_fd = 0, selected = 0;
u_int16_t port = 0;
+ struct pollfd pfd[] = {
+ { .fd = this->ipv4, .events = POLLIN },
+ { .fd = this->ipv4_natt, .events = POLLIN },
+ { .fd = this->ipv6, .events = POLLIN },
+ { .fd = this->ipv6_natt, .events = POLLIN },
+ };
+ int ports[] = {
+ /* port numbers assocaited to pollfds */
+ this->port, this->natt, this->port, this->natt,
+ };
- FD_ZERO(&rfds);
-
- if (this->ipv4 != -1)
- {
- FD_SET(this->ipv4, &rfds);
- max_fd = max(max_fd, this->ipv4);
- }
- if (this->ipv4_natt != -1)
- {
- FD_SET(this->ipv4_natt, &rfds);
- max_fd = max(max_fd, this->ipv4_natt);
- }
- if (this->ipv6 != -1)
- {
- FD_SET(this->ipv6, &rfds);
- max_fd = max(max_fd, this->ipv6);
- }
- if (this->ipv6_natt != -1)
- {
- FD_SET(this->ipv6_natt, &rfds);
- max_fd = max(max_fd, this->ipv6_natt);
- }
DBG2(DBG_NET, "waiting for data on sockets");
oldstate = thread_cancelability(TRUE);
- if (select(max_fd + 1, &rfds, NULL, NULL, NULL) <= 0)
+ if (poll(pfd, countof(pfd), -1) <= 0)
{
thread_cancelability(oldstate);
return FAILED;
}
thread_cancelability(oldstate);
- if (this->ipv4 != -1 && FD_ISSET(this->ipv4, &rfds))
- {
- port = this->port;
- selected = this->ipv4;
- }
- if (this->ipv4_natt != -1 && FD_ISSET(this->ipv4_natt, &rfds))
- {
- port = this->natt;
- selected = this->ipv4_natt;
- }
- if (this->ipv6 != -1 && FD_ISSET(this->ipv6, &rfds))
+ for (i = 0; i < countof(pfd); i++)
{
- port = this->port;
- selected = this->ipv6;
- }
- if (this->ipv6_natt != -1 && FD_ISSET(this->ipv6_natt, &rfds))
- {
- port = this->natt;
- selected = this->ipv6_natt;
+ if (pfd[i].revents & POLLIN)
+ {
+ selected = pfd[i].fd;
+ port = ports[i];
+ break;
+ }
}
- if (selected)
+ if (selected != -1)
{
struct msghdr msg;
struct cmsghdr *cmsgptr;