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;
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
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");
A WvFastString acts exactly like a WvString, but can take (const char *) strings without needing to a...
A raw memory read-only buffer backed by a constant WvString.
The basic interface which is included by all other XPLC interfaces and objects.
virtual const WvIPPortAddr * src() const
src() is a bit of a misnomer, but it returns the listener port.
void check_resolver()
Resolve the remote address, if it was fed in non-IP form.
void setfd(int fd)
Sets the file descriptor for both reading and writing.
virtual void seterr(int _errnum)
Set the errnum variable – we have an error.
WvTCPListener(const WvIPPortAddr &_listenport)
Create a WvStream that listens on _listenport of the current machine This is how you set up a TCP Ser...
bool isconnected() const
has the connection been completed yet?
void set_close_on_exec(bool close_on_exec)
Make the fds on this stream close-on-exec or not.
WvIPPortAddr localaddr()
the local address of this socket (ie.
int findaddr(int msec_timeout, WvStringParm name, WvIPAddr const **addr, WvIPAddrList *addrlist=NULL)
Return -1 on timeout, or the number of addresses found, which may be 0 if the address does not exist...
An IP+Port address also includes a port number, with the resulting form www.xxx.yyy.zzz:pppp.
WvTCPConn(int _fd, const WvIPPortAddr &_remaddr)
Start a WvTCPConn on an already-open socket (used by WvTCPListener)
virtual void pre_select(SelectInfo &si)
pre_select() sets up for eventually calling ::select().
An IP address is made up of a "dotted quad" – four decimal numbers in the form www.xxx.yyy.zzz.
int getfd() const
Returns the Unix file descriptor for reading and writing.
virtual bool post_select(SelectInfo &si)
override post_select() to set the 'connected' variable as soon as we are connected.
virtual void pre_select(SelectInfo &si)
override pre_select() to cause select() results when resolving names.
A type-safe version of WvMonikerBase that lets you provide create functions for object types other th...
void debug_mode()
function to set up a TCP socket the way we don't like: turn the timeouts way down so that network err...
Class to easily create the Server side of a WvTCPConn.
virtual size_t uwrite(const void *buf, size_t count)
unbuffered I/O functions; these ignore the buffer, which is handled by write().
void nice_tcpopts()
function to set up a TCP socket the way we like (Read/Write, Non-Blocking, KeepAlive) ...
char * edit()
make the string editable, and return a non-const (char*)
WvString wvtcl_getword(WvBuf &buf, const WvStringMask &splitchars=WVTCL_SPLITCHARS, bool do_unescape=true)
Get a single tcl word from an input buffer, and return the rest of the buffer untouched.
the data structure used by pre_select()/post_select() and internally by select(). ...
virtual bool isok() const
return true if the stream is actually usable right now
WvTCPConn tries to make all outgoing connections asynchronously (in the background).
Base class for streams built on Unix file descriptors.
void do_connect()
Connect to the remote end - note the "Protected" above ;)
virtual ~WvTCPConn()
Destructor - rarely do you need to call this - close() is a much better way to tear down a TCP Stream...
WvString hostname()
Do gethostname() without a fixed-length buffer.
void set_nonblock(bool nonblock)
Make the fds on this stream blocking or non-blocking.
void pre_select(WvStringParm hostname, WvStream::SelectInfo &si)
add all of our waiting fds to an fd_set for use with select().
virtual void seterr(int _errnum)
Override seterr() from WvError so that it auto-closes the stream.
virtual bool isok() const
Is this connection OK? Note: isok() will always be true if !resolved, even though fd==-1...
virtual bool isok() const
By default, returns true if geterr() == 0.
virtual const WvIPPortAddr * src() const
return the remote address (source of all incoming packets), which is a constant for any given TCP con...
bool post_select(WvStringParm hostname, WvStream::SelectInfo &si)
determines whether the resolving process is complete.
virtual bool post_select(SelectInfo &si)
post_select() is called after ::select(), and returns true if this object is now ready.
virtual size_t uwrite(const void *buf, size_t count)
unbuffered I/O functions; these ignore the buffer, which is handled by write().
void setcallback(IWvStreamCallback _callfunc)
define the callback function for this stream, called whenever the callback() member is run...
WvString is an implementation of a simple and efficient printable-string class.
virtual IWvStream * accept()
return a new WvTCPConn socket corresponding to a newly-accepted connection.
void low_delay()
function to set up a TCP socket the way we like In addition to the nice_tcpopts(), set TCP_NODELAY
WvStreamClone simply forwards all requests to the "cloned" stream.
virtual void addwrap(IWvListenerWrapper _wrapper)=0
Add a wrapper function for this stream: something that accept() will call to possibly wrap the stream...
WvStreamList holds a list of WvStream objects – and its select() and callback() functions know how t...