aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/options.c1
-rw-r--r--src/usocket.c2
-rw-r--r--src/wsocket.c117
3 files changed, 64 insertions, 56 deletions
diff --git a/src/options.c b/src/options.c
index 32a98d6..972844f 100644
--- a/src/options.c
+++ b/src/options.c
@@ -3,6 +3,7 @@
3 3
4#include "auxiliar.h" 4#include "auxiliar.h"
5#include "options.h" 5#include "options.h"
6#include "inet.h"
6 7
7static int opt_setmembership(lua_State *L, p_sock ps, int level, int name); 8static int opt_setmembership(lua_State *L, p_sock ps, int level, int name);
8static int opt_setboolean(lua_State *L, p_sock ps, int level, int name); 9static int opt_setboolean(lua_State *L, p_sock ps, int level, int name);
diff --git a/src/usocket.c b/src/usocket.c
index 54f203b..5afa1bf 100644
--- a/src/usocket.c
+++ b/src/usocket.c
@@ -140,7 +140,7 @@ int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len, p_tm tm)
140{ 140{
141 t_sock sock = *ps; 141 t_sock sock = *ps;
142 SA dummy_addr; 142 SA dummy_addr;
143 socklen_t dummy_len; 143 socklen_t dummy_len = sizeof(dummy_addr);
144 if (sock == SOCK_INVALID) return IO_CLOSED; 144 if (sock == SOCK_INVALID) return IO_CLOSED;
145 if (!addr) addr = &dummy_addr; 145 if (!addr) addr = &dummy_addr;
146 if (!addr_len) addr_len = &dummy_len; 146 if (!addr_len) addr_len = &dummy_len;
diff --git a/src/wsocket.c b/src/wsocket.c
index 5ea2e56..f834503 100644
--- a/src/wsocket.c
+++ b/src/wsocket.c
@@ -15,6 +15,10 @@
15 15
16#include "socket.h" 16#include "socket.h"
17 17
18static const char *sock_createstrerror(void);
19static const char *sock_bindstrerror(void);
20static const char *sock_connectstrerror(void);
21
18/*-------------------------------------------------------------------------*\ 22/*-------------------------------------------------------------------------*\
19* Initializes module 23* Initializes module
20\*-------------------------------------------------------------------------*/ 24\*-------------------------------------------------------------------------*/
@@ -53,63 +57,64 @@ void sock_shutdown(p_sock ps, int how)
53/*-------------------------------------------------------------------------*\ 57/*-------------------------------------------------------------------------*\
54* Creates and sets up a socket 58* Creates and sets up a socket
55\*-------------------------------------------------------------------------*/ 59\*-------------------------------------------------------------------------*/
56int sock_create(p_sock ps, int domain, int type, int protocol) 60const char *sock_create(p_sock ps, int domain, int type, int protocol)
57{ 61{
58 int val = 1; 62 int val = 1;
59 t_sock sock = socket(domain, type, protocol); 63 t_sock sock = socket(domain, type, protocol);
60 if (sock == SOCK_INVALID) return IO_ERROR; 64 if (sock == SOCK_INVALID) return sock_createstrerror();
61 *ps = sock; 65 *ps = sock;
62 sock_setnonblocking(ps); 66 sock_setnonblocking(ps);
63 setsockopt(*ps, SOL_SOCKET, SO_REUSEADDR, (char *) &val, sizeof(val)); 67 setsockopt(*ps, SOL_SOCKET, SO_REUSEADDR, (char *) &val, sizeof(val));
64 return IO_DONE; 68 return NULL;
65} 69}
66 70
67/*-------------------------------------------------------------------------*\ 71/*-------------------------------------------------------------------------*\
68* Connects or returns error message 72* Connects or returns error message
69\*-------------------------------------------------------------------------*/ 73\*-------------------------------------------------------------------------*/
70int sock_connect(p_sock ps, SA *addr, socklen_t addr_len, int timeout) 74const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len, p_tm tm)
71{ 75{
72 t_sock sock = *ps; 76 t_sock sock = *ps;
73 if (sock == SOCK_INVALID) return IO_CLOSED; 77 int err, timeout = tm_getretry(tm);
74 /* if connect fails, we have to find out why */ 78 struct timeval tv;
75 if (connect(sock, addr, addr_len) < 0) { 79 fd_set efds, wfds;
76 int err; 80 /* don't call on closed socket */
77 struct timeval tv; 81 if (sock == SOCK_INVALID) return io_strerror(IO_CLOSED);
78 fd_set efds, wfds; 82 /* ask system to connect */
79 /* make sure the system is trying to connect */ 83 err = connect(sock, addr, addr_len);
80 if (WSAGetLastError() != WSAEWOULDBLOCK) return IO_ERROR; 84 /* if no error, we're done */
81 tv.tv_sec = timeout / 1000; 85 if (err == 0) return NULL;
82 tv.tv_usec = (timeout % 1000) * 1000; 86 /* make sure the system is trying to connect */
83 FD_ZERO(&wfds); FD_SET(sock, &wfds); 87 if (WSAGetLastError() != WSAEWOULDBLOCK) return sock_connectstrerror();
84 FD_ZERO(&efds); FD_SET(sock, &efds); 88 /* wait for a timeout or for the system's answer */
85 /* we run select to avoid busy waiting */ 89 tv.tv_sec = timeout / 1000;
86 err = select(0, NULL, &wfds, &efds, timeout >= 0? &tv: NULL); 90 tv.tv_usec = (timeout % 1000) * 1000;
87 /* if select returned due to an event */ 91 FD_ZERO(&wfds); FD_SET(sock, &wfds);
88 if (err > 0 ) { 92 FD_ZERO(&efds); FD_SET(sock, &efds);
89 /* the sets tell whether it was a sucess or failure */ 93 /* we run select to wait */
90 if (FD_ISSET(sock,&efds) || !FD_ISSET(sock,&wfds)) { 94 err = select(0, NULL, &wfds, &efds, timeout >= 0? &tv: NULL);
91 int why; 95 /* if select returned due to an event */
92 int len = sizeof(why); 96 if (err > 0 ) {
93 /* find out why it failed */ 97 /* if was in efds, we failed */
94 getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)&why, &len); 98 if (FD_ISSET(sock,&efds) || !FD_ISSET(sock,&wfds)) {
95 WSASetLastError(why); 99 int why;
96 return IO_ERROR; 100 int len = sizeof(why);
97 } else return IO_DONE; 101 /* find out why we failed */
102 getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)&why, &len);
103 WSASetLastError(why);
104 return sock_connectstrerror();
105 /* if was in wfds, we succeeded */
106 } else return NULL;
98 /* if nothing happened, we timed out */ 107 /* if nothing happened, we timed out */
99 } else if (err == 0) return IO_TIMEOUT; 108 } else return io_strerror(IO_TIMEOUT);
100 /* otherwise, I don't know what happened */
101 else return IO_ERROR;
102 /* otherwise, it worked */
103 } else return IO_DONE;
104} 109}
105 110
106/*-------------------------------------------------------------------------*\ 111/*-------------------------------------------------------------------------*\
107* Binds or returns error message 112* Binds or returns error message
108\*-------------------------------------------------------------------------*/ 113\*-------------------------------------------------------------------------*/
109int sock_bind(p_sock ps, SA *addr, socklen_t addr_len) 114const char *sock_bind(p_sock ps, SA *addr, socklen_t addr_len)
110{ 115{
111 if (bind(*ps, addr, addr_len) < 0) return IO_ERROR; 116 if (bind(*ps, addr, addr_len) < 0) return sock_bindstrerror();
112 else return IO_DONE; 117 else return NULL;
113} 118}
114 119
115/*-------------------------------------------------------------------------*\ 120/*-------------------------------------------------------------------------*\
@@ -123,27 +128,29 @@ void sock_listen(p_sock ps, int backlog)
123/*-------------------------------------------------------------------------*\ 128/*-------------------------------------------------------------------------*\
124* Accept with timeout 129* Accept with timeout
125\*-------------------------------------------------------------------------*/ 130\*-------------------------------------------------------------------------*/
126int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len, 131int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len, p_tm tm)
127 int timeout)
128{ 132{
129 t_sock sock = *ps; 133 t_sock sock = *ps;
130 struct timeval tv;
131 SA dummy_addr; 134 SA dummy_addr;
132 socklen_t dummy_len; 135 socklen_t dummy_len = sizeof(dummy_addr);
133 fd_set fds;
134 if (sock == SOCK_INVALID) return IO_CLOSED; 136 if (sock == SOCK_INVALID) return IO_CLOSED;
135 tv.tv_sec = timeout / 1000;
136 tv.tv_usec = (timeout % 1000) * 1000;
137 FD_ZERO(&fds);
138 FD_SET(sock, &fds);
139 *pa = SOCK_INVALID;
140 if (select(0, &fds, NULL, NULL, timeout >= 0 ? &tv : NULL) <= 0)
141 return IO_TIMEOUT;
142 if (!addr) addr = &dummy_addr; 137 if (!addr) addr = &dummy_addr;
143 if (!addr_len) addr_len = &dummy_len; 138 if (!addr_len) addr_len = &dummy_len;
144 *pa = accept(sock, addr, addr_len); 139 for (;;) {
145 if (*pa == SOCK_INVALID) return IO_ERROR; 140 int timeout = tm_getretry(tm);
146 else return IO_DONE; 141 struct timeval tv;
142 fd_set fds;
143 *pa = accept(sock, addr, addr_len);
144 if (*pa != SOCK_INVALID) return IO_DONE;
145 if (timeout == 0) return IO_TIMEOUT;
146 tv.tv_sec = timeout / 1000;
147 tv.tv_usec = (timeout % 1000) * 1000;
148 FD_ZERO(&fds);
149 FD_SET(sock, &fds);
150 /* call select just to avoid busy-wait. */
151 select(0, &fds, NULL, NULL, timeout >= 0? &tv: NULL);
152 }
153 return IO_TIMEOUT; /* can't get here */
147} 154}
148 155
149/*-------------------------------------------------------------------------*\ 156/*-------------------------------------------------------------------------*\
@@ -313,7 +320,7 @@ const char *sock_hoststrerror(void)
313 } 320 }
314} 321}
315 322
316const char *sock_createstrerror(void) 323static const char *sock_createstrerror(void)
317{ 324{
318 switch (WSAGetLastError()) { 325 switch (WSAGetLastError()) {
319 case WSANOTINITIALISED: return "not initialized"; 326 case WSANOTINITIALISED: return "not initialized";
@@ -324,7 +331,7 @@ const char *sock_createstrerror(void)
324 } 331 }
325} 332}
326 333
327const char *sock_bindstrerror(void) 334static const char *sock_bindstrerror(void)
328{ 335{
329 switch (WSAGetLastError()) { 336 switch (WSAGetLastError()) {
330 case WSANOTINITIALISED: return "not initialized"; 337 case WSANOTINITIALISED: return "not initialized";
@@ -338,7 +345,7 @@ const char *sock_bindstrerror(void)
338 } 345 }
339} 346}
340 347
341const char *sock_connectstrerror(void) 348static const char *sock_connectstrerror(void)
342{ 349{
343 switch (WSAGetLastError()) { 350 switch (WSAGetLastError()) {
344 case WSANOTINITIALISED: return "not initialized"; 351 case WSANOTINITIALISED: return "not initialized";