7 #include "wvtcplistener.h"
9 #include "wvistreamlist.h"
10 #include "wvmoniker.h"
11 #include "wvlinkerhack.h"
15 #define setsockopt(a,b,c,d,e) setsockopt(a,b,c, (const char*) d,e)
16 #define getsockopt(a,b,c,d,e) getsockopt(a,b,c,(char *)d, e)
18 #define errno GetLastError()
19 #define EWOULDBLOCK WSAEWOULDBLOCK
20 #define EINPROGRESS WSAEINPROGRESS
21 #define EISCONN WSAEISCONN
22 #define EALREADY WSAEALREADY
24 #define EINVAL WSAEINVAL
25 #define SOL_TCP IPPROTO_TCP
26 #define SOL_IP IPPROTO_IP
27 #define FORCE_NONZERO 1
34 # include <sys/socket.h>
40 # include <netinet/in.h>
43 # if HAVE_NETINET_IN_SYSTM_H
44 # include <netinet/in_systm.h>
46 # include <netinet/ip.h>
48 #if HAVE_NETINET_TCP_H
49 # include <netinet/tcp.h>
53 #define FORCE_NONZERO 0
85 l->
addwrap(wv::bind(&IWvStream::create, wrapper, _1));
94 remaddr = (_remaddr.is_zero() && FORCE_NONZERO)
107 remaddr = (_remaddr.is_zero() && FORCE_NONZERO)
119 struct servent* serv;
120 char *hnstr = hostname.
edit(), *cptr;
122 cptr = strchr(hnstr,
':');
124 cptr = strchr(hnstr,
'\t');
126 cptr = strchr(hnstr,
' ');
130 serv = getservbyname(cptr, NULL);
131 remaddr.port = serv ? ntohs(serv->s_port) : atoi(cptr);
135 remaddr.port = _port;
137 resolved = connected =
false;
166 setsockopt(
getfd(), SOL_SOCKET, SO_KEEPALIVE, &value,
sizeof(value));
176 setsockopt(
getfd(), SOL_TCP, TCP_NODELAY, &value,
sizeof(value));
179 value = IPTOS_LOWDELAY;
180 setsockopt(
getfd(), SOL_IP, IP_TOS, &value,
sizeof(value));
188 setsockopt(
getfd(), SOL_SOCKET, SO_KEEPALIVE, &value,
sizeof(value));
195 int rwfd = socket(PF_INET, SOCK_STREAM, 0);
216 sockaddr *sa = newaddr.sockaddr();
217 int ret = connect(
getfd(), sa, newaddr.sockaddr_len()), err = errno;
220 if (ret == 0 || (ret < 0 && err == EISCONN))
223 && err != EINPROGRESS
224 && err != EWOULDBLOCK
239 int dnsres = dns.
findaddr(0, hostname, &ipr);
256 #ifndef SO_ORIGINAL_DST
257 # define SO_ORIGINAL_DST 80
263 socklen_t sl =
sizeof(sin);
273 (!incoming || getsockopt(
getfd(), SOL_IP,
274 SO_ORIGINAL_DST, (
char*)&sin, &sl) < 0) &&
276 getsockname(
getfd(), (sockaddr *)&sin, &sl))
298 bool oldw = si.wants.writable;
300 si.wants.writable =
true;
310 si.wants.isexception =
true;
314 si.wants.writable = oldw;
336 if (result && !connected)
349 socklen_t res_size =
sizeof(conn_res);
350 if (getsockopt(
getfd(), SOL_SOCKET, SO_ERROR,
351 &conn_res, &res_size))
357 else if (conn_res != 0)
396 listenport = _listenport;
397 sockaddr *sa = listenport.sockaddr();
404 || setsockopt(getfd(), SOL_SOCKET, SO_REUSEADDR, &x,
sizeof(x))
405 || bind(getfd(), sa, listenport.sockaddr_len())
406 || listen(getfd(), 5))
412 if (listenport.port == 0)
414 socklen_t namelen = listenport.sockaddr_len();
416 if (getsockname(getfd(), sa, &namelen) != 0)
426 WvTCPListener::~WvTCPListener()
434 struct sockaddr_in sin;
435 socklen_t len =
sizeof(sin);
437 if (!
isok())
return NULL;
439 int newfd =
::accept(getfd(), (
struct sockaddr *)&sin, &len);
442 else if (errno == EAGAIN || errno == EINTR)
458 list->append(conn,
true,
"WvTCPConn");