version 3.0
This commit is contained in:
commit
d837490606
209 changed files with 19662 additions and 0 deletions
4
io/Makefile
Normal file
4
io/Makefile
Normal file
|
@ -0,0 +1,4 @@
|
|||
SUBDIR+=net
|
||||
SUBDIR+=socket
|
||||
|
||||
include ../common/subdir.mk
|
5
io/lib.mk
Normal file
5
io/lib.mk
Normal file
|
@ -0,0 +1,5 @@
|
|||
VPATH+= ${TOPDIR}/io
|
||||
|
||||
SRCS+= stream_handle.cc
|
||||
SRCS+= sink_filter.cc
|
||||
|
0
io/net/Makefile
Normal file
0
io/net/Makefile
Normal file
4
io/net/lib.mk
Normal file
4
io/net/lib.mk
Normal file
|
@ -0,0 +1,4 @@
|
|||
VPATH+= ${TOPDIR}/io/net
|
||||
|
||||
SRCS+= tcp_server.cc
|
||||
SRCS+= udp_server.cc
|
64
io/net/tcp_server.cc
Normal file
64
io/net/tcp_server.cc
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2012 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <io/net/tcp_server.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: tcp_server.cc //
|
||||
// Description: base class for a connection oriented network server //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TCPServer::listen (SocketAddressFamily family, const std::string& name)
|
||||
{
|
||||
if (socket_)
|
||||
{
|
||||
socket_->close (0);
|
||||
delete socket_;
|
||||
}
|
||||
|
||||
socket_ = Socket::create (family, SocketTypeStream, "tcp", name);
|
||||
if (! socket_)
|
||||
{
|
||||
ERROR("/tcp/server") << "Unable to create socket.";
|
||||
return false;
|
||||
}
|
||||
if (! socket_->bind (name))
|
||||
{
|
||||
ERROR("/tcp/server") << "Socket bind failed";
|
||||
return false;
|
||||
}
|
||||
if (! socket_->listen ())
|
||||
{
|
||||
ERROR("/tcp/server") << "Socket listen failed";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
73
io/net/tcp_server.h
Normal file
73
io/net/tcp_server.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2011 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef IO_NET_TCP_SERVER_H
|
||||
#define IO_NET_TCP_SERVER_H
|
||||
|
||||
#include <io/socket/socket.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: tcp_server.h //
|
||||
// Description: base class for a connection oriented network server //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class TCPServer
|
||||
{
|
||||
LogHandle log_;
|
||||
Socket* socket_;
|
||||
|
||||
public:
|
||||
TCPServer () : log_("/tcp/server"), socket_(0)
|
||||
{ }
|
||||
|
||||
~TCPServer ()
|
||||
{
|
||||
delete socket_;
|
||||
}
|
||||
|
||||
bool listen (SocketAddressFamily family, const std::string& name);
|
||||
|
||||
Action* accept (SocketEventCallback* cb)
|
||||
{
|
||||
return (socket_ ? socket_->accept (cb) : 0);
|
||||
}
|
||||
|
||||
Action* close (EventCallback* cb = 0)
|
||||
{
|
||||
return (socket_ ? socket_->close (cb) : 0);
|
||||
}
|
||||
|
||||
std::string getsockname () const
|
||||
{
|
||||
return (socket_ ? socket_->getsockname () : std::string ());
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* !IO_NET_TCP_SERVER_H */
|
59
io/net/udp_server.cc
Normal file
59
io/net/udp_server.cc
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2010 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <io/net/udp_server.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: udp_server.cc //
|
||||
// Description: base class for a datagram network server //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool UDPServer::listen (SocketAddressFamily family, const std::string& name)
|
||||
{
|
||||
if (socket_)
|
||||
{
|
||||
socket_->close (0);
|
||||
delete socket_;
|
||||
}
|
||||
|
||||
socket_ = Socket::create (family, SocketTypeDatagram, "udp", name);
|
||||
if (! socket_)
|
||||
{
|
||||
ERROR("/udp/server") << "Unable to create socket.";
|
||||
return false;
|
||||
}
|
||||
if (! socket_->bind (name))
|
||||
{
|
||||
ERROR("/udp/server") << "Socket bind failed";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
73
io/net/udp_server.h
Normal file
73
io/net/udp_server.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2011 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef IO_NET_UDP_SERVER_H
|
||||
#define IO_NET_UDP_SERVER_H
|
||||
|
||||
#include <io/socket/socket.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: udp_server.h //
|
||||
// Description: base class for a datagram network server //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class UDPServer
|
||||
{
|
||||
LogHandle log_;
|
||||
Socket* socket_;
|
||||
|
||||
public:
|
||||
UDPServer () : log_("/udp/server"), socket_(0)
|
||||
{ }
|
||||
|
||||
~UDPServer ()
|
||||
{
|
||||
delete socket_;
|
||||
}
|
||||
|
||||
bool listen (SocketAddressFamily family, const std::string& name);
|
||||
|
||||
Action* read (EventCallback* cb)
|
||||
{
|
||||
return (socket_ ? socket_->read (cb) : 0);
|
||||
}
|
||||
|
||||
Action* close (EventCallback* cb)
|
||||
{
|
||||
return (socket_ ? socket_->close (cb) : 0);
|
||||
}
|
||||
|
||||
std::string getsockname (void) const
|
||||
{
|
||||
return (socket_ ? socket_->getsockname () : std::string ());
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* !IO_NET_UDP_SERVER_H */
|
74
io/sink_filter.cc
Normal file
74
io/sink_filter.cc
Normal file
|
@ -0,0 +1,74 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: sink_filter.cc //
|
||||
// Description: a filter to write into a target device //
|
||||
// Project: WANProxy XTech //
|
||||
// Author: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/errno.h>
|
||||
#include "sink_filter.h"
|
||||
|
||||
SinkFilter::SinkFilter (const LogHandle& log, Socket* sck, bool cln) : BufferedFilter (log)
|
||||
{
|
||||
sink_ = sck; write_action_ = 0; client_ = cln, down_ = closing_ = false;
|
||||
}
|
||||
|
||||
SinkFilter::~SinkFilter ()
|
||||
{
|
||||
if (write_action_) write_action_->cancel ();
|
||||
}
|
||||
|
||||
bool SinkFilter::consume (Buffer& buf)
|
||||
{
|
||||
if (! sink_ || closing_)
|
||||
return false;
|
||||
|
||||
if (write_action_)
|
||||
pending_.append (buf);
|
||||
else
|
||||
write_action_ = sink_->write (buf, callback (this, &SinkFilter::write_complete));
|
||||
|
||||
return (write_action_ != 0);
|
||||
}
|
||||
|
||||
void SinkFilter::write_complete (Event e)
|
||||
{
|
||||
if (write_action_)
|
||||
write_action_->cancel (), write_action_ = 0;
|
||||
|
||||
switch (e.type_)
|
||||
{
|
||||
case Event::Done:
|
||||
if (! pending_.empty ())
|
||||
{
|
||||
write_action_ = sink_->write (pending_, callback (this, &SinkFilter::write_complete));
|
||||
pending_.clear ();
|
||||
}
|
||||
else if (flushing_)
|
||||
flush (0);
|
||||
break;
|
||||
case Event::Error:
|
||||
if (e.error_ == EPIPE && client_)
|
||||
DEBUG(log_) << "Client closed connection";
|
||||
else
|
||||
ERROR(log_) << "Write failed: " << e;
|
||||
closing_ = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SinkFilter::flush (int flg)
|
||||
{
|
||||
flushing_ = true;
|
||||
flush_flags_ |= flg;
|
||||
if (flushing_ && ! write_action_)
|
||||
{
|
||||
if (! down_)
|
||||
down_ = (sink_->shutdown (false, true) == 0);
|
||||
Filter::flush (flush_flags_);
|
||||
}
|
||||
}
|
31
io/sink_filter.h
Normal file
31
io/sink_filter.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: sink_filter.h //
|
||||
// Description: a filter to write into a target device //
|
||||
// Project: WANProxy XTech //
|
||||
// Author: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <common/filter.h>
|
||||
#include <event/action.h>
|
||||
#include <event/event.h>
|
||||
#include <io/socket/socket.h>
|
||||
|
||||
class SinkFilter : public BufferedFilter
|
||||
{
|
||||
private:
|
||||
Socket* sink_;
|
||||
Action* write_action_;
|
||||
bool client_, down_, closing_;
|
||||
|
||||
public:
|
||||
SinkFilter (const LogHandle& log, Socket* sck, bool cln = 0);
|
||||
virtual ~SinkFilter ();
|
||||
|
||||
virtual bool consume (Buffer& buf);
|
||||
void write_complete (Event e);
|
||||
virtual void flush (int flg);
|
||||
};
|
||||
|
0
io/socket/Makefile
Normal file
0
io/socket/Makefile
Normal file
15
io/socket/lib.mk
Normal file
15
io/socket/lib.mk
Normal file
|
@ -0,0 +1,15 @@
|
|||
VPATH+= ${TOPDIR}/io/socket
|
||||
|
||||
SRCS+= socket.cc
|
||||
SRCS+= unix_server.cc
|
||||
|
||||
ifeq "${OSNAME}" "Haiku"
|
||||
# Required for sockets.
|
||||
LDADD+= -lnetwork
|
||||
endif
|
||||
|
||||
ifeq "${OSNAME}" "SunOS"
|
||||
# Required for sockets.
|
||||
LDADD+= -lnsl
|
||||
LDADD+= -lsocket
|
||||
endif
|
582
io/socket/socket.cc
Normal file
582
io/socket/socket.cc
Normal file
|
@ -0,0 +1,582 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2012 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <common/endian.h>
|
||||
#include <event/event_system.h>
|
||||
#include <io/socket/socket.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: socket.cc //
|
||||
// Description: a stream handle for network connections //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
* XXX Presently using AF_INET6 as the test for what is supported, but that is
|
||||
* wrong in many, many ways.
|
||||
*/
|
||||
|
||||
#if defined(__OPENNT)
|
||||
struct addrinfo {
|
||||
int ai_family;
|
||||
int ai_socktype;
|
||||
int ai_protocol;
|
||||
struct sockaddr *ai_addr;
|
||||
socklen_t ai_addrlen;
|
||||
|
||||
struct sockaddr_in _ai_inet;
|
||||
};
|
||||
|
||||
static int
|
||||
getaddrinfo(const char *host, const char *serv, const struct addrinfo *hints,
|
||||
struct addrinfo **aip)
|
||||
{
|
||||
struct addrinfo *ai;
|
||||
struct hostent *he;
|
||||
|
||||
he = gethostbyname(host);
|
||||
if (he == NULL)
|
||||
return (1);
|
||||
|
||||
ai = new addrinfo;
|
||||
ai->ai_family = AF_INET;
|
||||
ai->ai_socktype = hints->ai_socktype;
|
||||
ai->ai_protocol = hints->ai_protocol;
|
||||
ai->ai_addr = (struct sockaddr *)&ai->_ai_inet;
|
||||
ai->ai_addrlen = sizeof ai->_ai_inet;
|
||||
|
||||
memset(&ai->_ai_inet, 0, sizeof ai->_ai_inet);
|
||||
ai->_ai_inet.sin_family = AF_INET;
|
||||
/* XXX _ai_inet.sin_addr on non-__OPENNT */
|
||||
|
||||
ASSERT(log_, he->h_length == sizeof ai->_ai_inet.sin_addr);
|
||||
memcpy(&ai->_ai_inet.sin_addr, he->h_addr_list[0], he->h_length);
|
||||
|
||||
if (serv != NULL) {
|
||||
unsigned long port;
|
||||
char *end;
|
||||
|
||||
port = strtoul(serv, &end, 0);
|
||||
if (*end == '\0') {
|
||||
ai->_ai_inet.sin_port = htons(port);
|
||||
} else {
|
||||
struct protoent *pe;
|
||||
struct servent *se;
|
||||
|
||||
pe = getprotobynumber(ai->ai_protocol);
|
||||
if (pe == NULL) {
|
||||
free(ai);
|
||||
return (2);
|
||||
}
|
||||
|
||||
se = getservbyname(serv, pe->p_name);
|
||||
if (se == NULL) {
|
||||
free(ai);
|
||||
return (3);
|
||||
}
|
||||
|
||||
ai->_ai_inet.sin_port = se->s_port;
|
||||
}
|
||||
}
|
||||
|
||||
*aip = ai;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static const char *
|
||||
gai_strerror(int rv)
|
||||
{
|
||||
switch (rv) {
|
||||
case 1:
|
||||
return "could not look up host";
|
||||
case 2:
|
||||
return "could not look up protocol";
|
||||
case 3:
|
||||
return "could not look up service";
|
||||
default:
|
||||
NOTREACHED(log_);
|
||||
return "internal error";
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
freeaddrinfo(struct addrinfo *ai)
|
||||
{
|
||||
delete ai;
|
||||
}
|
||||
|
||||
#define NI_MAXHOST 1024
|
||||
#define NI_MAXSERV 16
|
||||
#define NI_NUMERICHOST 0
|
||||
#define NI_NUMERICSERV 0
|
||||
|
||||
static int
|
||||
getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host,
|
||||
size_t hostlen, char *serv, size_t servlen, int flags)
|
||||
{
|
||||
struct sockaddr_in *inet = (struct sockaddr_in *)sa;
|
||||
char *p;
|
||||
|
||||
if (inet->sin_family != AF_INET || salen != sizeof *inet || flags != 0)
|
||||
return (ENOTSUP);
|
||||
|
||||
p = inet_ntoa(inet->sin_addr);
|
||||
if (p == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
snprintf(host, hostlen, "%s", p);
|
||||
snprintf(serv, servlen, "%hu", ntohs(inet->sin_port));
|
||||
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct socket_address {
|
||||
union address_union {
|
||||
struct sockaddr sockaddr_;
|
||||
struct sockaddr_in inet_;
|
||||
#if defined(AF_INET6)
|
||||
struct sockaddr_in6 inet6_;
|
||||
#endif
|
||||
struct sockaddr_un unix_;
|
||||
} addr_;
|
||||
socklen_t addrlen_;
|
||||
|
||||
socket_address(void)
|
||||
: addr_(),
|
||||
addrlen_(0)
|
||||
{
|
||||
memset(&addr_, 0, sizeof addr_);
|
||||
}
|
||||
|
||||
bool operator() (int domain, int socktype, int protocol, const std::string& str)
|
||||
{
|
||||
switch (domain) {
|
||||
#if defined(AF_INET6)
|
||||
case AF_UNSPEC:
|
||||
case AF_INET6:
|
||||
#endif
|
||||
case AF_INET:
|
||||
{
|
||||
std::string name;
|
||||
std::string service;
|
||||
|
||||
std::string::size_type pos = str.find(']');
|
||||
if (pos != std::string::npos) {
|
||||
if (pos < 3 || str[0] != '[' || str[pos + 1] != ':')
|
||||
return (false);
|
||||
name = str.substr(1, pos - 1);
|
||||
service = str.substr(pos + 2);
|
||||
} else {
|
||||
pos = str.find(':');
|
||||
if (pos == std::string::npos)
|
||||
return (false);
|
||||
name = str.substr(0, pos);
|
||||
service = str.substr(pos + 1);
|
||||
}
|
||||
|
||||
struct addrinfo hints;
|
||||
|
||||
memset(&hints, 0, sizeof hints);
|
||||
hints.ai_family = domain;
|
||||
hints.ai_socktype = socktype;
|
||||
hints.ai_protocol = protocol;
|
||||
|
||||
/*
|
||||
* Mac OS X ~Snow Leopard~ cannot handle a service name
|
||||
* of "0" where older Mac OS X could. Don't know if
|
||||
* that is because it's not in services(5) or due to
|
||||
* some attempt at input validation. So work around it
|
||||
* here, sigh.
|
||||
*/
|
||||
const char *servptr;
|
||||
if (service == "" || service == "0")
|
||||
servptr = NULL;
|
||||
else
|
||||
servptr = service.c_str();
|
||||
|
||||
struct addrinfo *ai;
|
||||
int rv = getaddrinfo(name.c_str(), servptr, &hints, &ai);
|
||||
if (rv != 0) {
|
||||
ERROR("/socket/address") << "Could not look up " << str << ": " << gai_strerror(rv);
|
||||
return (false);
|
||||
}
|
||||
|
||||
/*
|
||||
* Just use the first one.
|
||||
* XXX Will we ever get one in the wrong family? Is the hint mandatory?
|
||||
*/
|
||||
memcpy(&addr_.sockaddr_, ai->ai_addr, ai->ai_addrlen);
|
||||
addrlen_ = ai->ai_addrlen;
|
||||
|
||||
freeaddrinfo(ai);
|
||||
break;
|
||||
}
|
||||
case AF_UNIX:
|
||||
addr_.unix_.sun_family = domain;
|
||||
snprintf(addr_.unix_.sun_path, sizeof addr_.unix_.sun_path, "%s", str.c_str());
|
||||
addrlen_ = sizeof addr_.unix_;
|
||||
#if !defined(__linux__) && !defined(__sun__) && !defined(__OPENNT)
|
||||
addr_.unix_.sun_len = addrlen_;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
ERROR("/socket/address") << "Addresss family not supported: " << domain;
|
||||
return (false);
|
||||
}
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
operator std::string (void) const
|
||||
{
|
||||
std::ostringstream str;
|
||||
|
||||
switch (addr_.sockaddr_.sa_family) {
|
||||
#if defined(AF_INET6)
|
||||
case AF_INET6:
|
||||
#endif
|
||||
case AF_INET:
|
||||
{
|
||||
char host[NI_MAXHOST], serv[NI_MAXSERV];
|
||||
int flags;
|
||||
int rv;
|
||||
|
||||
/* XXX If we ever support !NI_NUMERICSERV, need NI_DGRAM for UDP. */
|
||||
flags = NI_NUMERICHOST | NI_NUMERICSERV;
|
||||
|
||||
rv = getnameinfo(&addr_.sockaddr_, addrlen_, host, sizeof host, serv, sizeof serv, flags);
|
||||
if (rv == -1)
|
||||
return ("<getnameinfo-error>");
|
||||
|
||||
str << '[' << host << ']' << ':' << serv;
|
||||
break;
|
||||
}
|
||||
case AF_UNIX:
|
||||
str << addr_.unix_.sun_path;
|
||||
break;
|
||||
default:
|
||||
return ("<address-family-not-supported>");
|
||||
}
|
||||
|
||||
return (str.str());
|
||||
}
|
||||
};
|
||||
|
||||
Socket::Socket (int fd, int domain, int socktype, int protocol)
|
||||
: StreamHandle(fd),
|
||||
log_("/socket"),
|
||||
domain_(domain),
|
||||
socktype_(socktype),
|
||||
protocol_(protocol),
|
||||
accept_request_(0),
|
||||
accept_check_(0)
|
||||
{
|
||||
ASSERT(log_, fd_ != -1);
|
||||
}
|
||||
|
||||
Action* Socket::accept (SocketEventCallback* cb)
|
||||
{
|
||||
ASSERT(log_, accept_request_ == 0);
|
||||
ASSERT(log_, accept_check_ == 0);
|
||||
|
||||
accept_request_ = new SocketEventAction (this, &Socket::accept_cancel, cb);
|
||||
accept_check_ = event_system.track (fd_, StreamModeAccept, callback (this, &Socket::accept_complete));
|
||||
|
||||
return accept_request_;
|
||||
}
|
||||
|
||||
void Socket::accept_complete (Event e)
|
||||
{
|
||||
SocketEventCallback* cb;
|
||||
|
||||
if (accept_check_)
|
||||
accept_check_->cancel (), accept_check_ = 0;
|
||||
|
||||
if (accept_request_ && (cb = accept_request_->callback_))
|
||||
{
|
||||
switch (e.type_)
|
||||
{
|
||||
case Event::Done:
|
||||
break;
|
||||
case Event::EOS:
|
||||
DEBUG(log_) << "Got EOS while waiting for accept: " << e;
|
||||
e.type_ = Event::Error;
|
||||
case Event::Error:
|
||||
cb->param (e, 0);
|
||||
cb->execute ();
|
||||
return;
|
||||
default:
|
||||
HALT(log_) << "Unexpected event: " << e;
|
||||
}
|
||||
|
||||
int s = ::accept (fd_, 0, 0);
|
||||
if (s == -1)
|
||||
{
|
||||
switch (errno)
|
||||
{
|
||||
case EAGAIN:
|
||||
return;
|
||||
default:
|
||||
cb->param (Event(Event::Error, errno), 0);
|
||||
cb->execute ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Socket* sck = new Socket (s, domain_, socktype_, protocol_);
|
||||
cb->param (Event::Done, sck);
|
||||
cb->execute ();
|
||||
|
||||
accept_check_ = event_system.track (fd_, StreamModeAccept, callback (this, &Socket::accept_complete));
|
||||
}
|
||||
}
|
||||
|
||||
void Socket::accept_cancel (void)
|
||||
{
|
||||
if (accept_check_)
|
||||
accept_check_->cancel (), accept_check_ = 0;
|
||||
|
||||
delete accept_request_;
|
||||
accept_request_ = 0;
|
||||
}
|
||||
|
||||
Action* Socket::connect (const std::string& name, EventCallback* cb)
|
||||
{
|
||||
socket_address addr;
|
||||
|
||||
if (! addr (domain_, socktype_, protocol_, name))
|
||||
{
|
||||
ERROR(log_) << "Invalid name for connect: " << name;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cb)
|
||||
cb->param ().buffer_ = Buffer ((uint8_t*) &addr.addr_.sockaddr_, addr.addrlen_);
|
||||
|
||||
return event_system.track (fd_, StreamModeConnect, cb);
|
||||
}
|
||||
|
||||
bool Socket::bind (const std::string& name)
|
||||
{
|
||||
socket_address addr;
|
||||
|
||||
if (! addr (domain_, socktype_, protocol_, name))
|
||||
{
|
||||
ERROR(log_) << "Invalid name for bind: " << name;
|
||||
return (false);
|
||||
}
|
||||
|
||||
int on = 1;
|
||||
int rv = setsockopt (fd_, SOL_SOCKET, SO_REUSEADDR, &on, sizeof on);
|
||||
if (rv == -1)
|
||||
ERROR(log_) << "Could not setsockopt(SO_REUSEADDR): " << strerror(errno);
|
||||
|
||||
rv = ::bind (fd_, &addr.addr_.sockaddr_, addr.addrlen_);
|
||||
if (rv == -1)
|
||||
{
|
||||
ERROR(log_) << "Could not bind: " << strerror(errno);
|
||||
return (false);
|
||||
}
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
bool Socket::listen (void)
|
||||
{
|
||||
int rv = ::listen (fd_, 128);
|
||||
return (rv != -1);
|
||||
}
|
||||
|
||||
bool Socket::shutdown (bool shut_read, bool shut_write)
|
||||
{
|
||||
int how;
|
||||
|
||||
if (shut_read && shut_write)
|
||||
how = SHUT_RDWR;
|
||||
else if (shut_read)
|
||||
how = SHUT_RD;
|
||||
else if (shut_write)
|
||||
how = SHUT_WR;
|
||||
else
|
||||
how = 0;
|
||||
|
||||
int rv = ::shutdown (fd_, how);
|
||||
return (rv != -1);
|
||||
}
|
||||
|
||||
std::string Socket::getpeername (void) const
|
||||
{
|
||||
socket_address sa;
|
||||
int rv;
|
||||
|
||||
sa.addrlen_ = sizeof sa.addr_;
|
||||
rv = ::getpeername(fd_, &sa.addr_.sockaddr_, &sa.addrlen_);
|
||||
if (rv == -1)
|
||||
return ("<unknown>");
|
||||
|
||||
/* XXX Check len. */
|
||||
|
||||
return ((std::string)sa);
|
||||
}
|
||||
|
||||
std::string Socket::getsockname (void) const
|
||||
{
|
||||
socket_address sa;
|
||||
int rv;
|
||||
|
||||
sa.addrlen_ = sizeof sa.addr_;
|
||||
rv = ::getsockname(fd_, &sa.addr_.sockaddr_, &sa.addrlen_);
|
||||
if (rv == -1)
|
||||
return ("<unknown>");
|
||||
|
||||
/* XXX Check len. */
|
||||
|
||||
return ((std::string)sa);
|
||||
}
|
||||
|
||||
Socket* Socket::create(SocketAddressFamily family, SocketType type, const std::string& protocol, const std::string& hint)
|
||||
{
|
||||
int typenum;
|
||||
|
||||
switch (type) {
|
||||
case SocketTypeStream:
|
||||
typenum = SOCK_STREAM;
|
||||
break;
|
||||
|
||||
case SocketTypeDatagram:
|
||||
typenum = SOCK_DGRAM;
|
||||
break;
|
||||
|
||||
default:
|
||||
ERROR("/socket") << "Unsupported socket type.";
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int protonum;
|
||||
|
||||
if (protocol == "") {
|
||||
protonum = 0;
|
||||
} else {
|
||||
struct protoent *proto = getprotobyname(protocol.c_str());
|
||||
if (proto == NULL) {
|
||||
ERROR("/socket") << "Invalid protocol: " << protocol;
|
||||
return (NULL);
|
||||
}
|
||||
protonum = proto->p_proto;
|
||||
}
|
||||
|
||||
int domainnum;
|
||||
|
||||
switch (family) {
|
||||
case SocketAddressFamilyIP:
|
||||
#if defined(AF_INET6)
|
||||
if (hint == "") {
|
||||
ERROR("/socket") << "Must specify hint address for IP sockets or specify IPv4 or IPv6 explicitly.";
|
||||
return (NULL);
|
||||
} else {
|
||||
socket_address addr;
|
||||
|
||||
if (!addr(AF_UNSPEC, typenum, protonum, hint)) {
|
||||
ERROR("/socket") << "Invalid hint: " << hint;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* XXX Just make socket_address::operator() smarter about AF_UNSPEC? */
|
||||
switch (addr.addr_.sockaddr_.sa_family) {
|
||||
case AF_INET:
|
||||
domainnum = AF_INET;
|
||||
break;
|
||||
|
||||
case AF_INET6:
|
||||
domainnum = AF_INET6;
|
||||
break;
|
||||
|
||||
default:
|
||||
ERROR("/socket") << "Unsupported address family for hint: " << hint;
|
||||
return (NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#else
|
||||
(void)hint;
|
||||
domainnum = AF_INET;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case SocketAddressFamilyIPv4:
|
||||
domainnum = AF_INET;
|
||||
break;
|
||||
|
||||
#if defined(AF_INET6)
|
||||
case SocketAddressFamilyIPv6:
|
||||
domainnum = AF_INET6;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case SocketAddressFamilyUnix:
|
||||
domainnum = AF_UNIX;
|
||||
break;
|
||||
|
||||
default:
|
||||
ERROR("/socket") << "Unsupported address family.";
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int s = ::socket(domainnum, typenum, protonum);
|
||||
if (s == -1) {
|
||||
#if defined(AF_INET6)
|
||||
/*
|
||||
* If we were trying to create an IPv6 socket for a request that
|
||||
* did not specify IPv4 vs. IPv6 and the system claims that the
|
||||
* protocol is not supported, try explicitly creating an IPv4
|
||||
* socket.
|
||||
*/
|
||||
if (errno == EPROTONOSUPPORT && domainnum == AF_INET6 &&
|
||||
family == SocketAddressFamilyIP) {
|
||||
DEBUG("/socket") << "IPv6 socket create failed; trying IPv4.";
|
||||
return (Socket::create(SocketAddressFamilyIPv4, type, protocol, hint));
|
||||
}
|
||||
#endif
|
||||
ERROR("/socket") << "Could not create socket: " << strerror(errno);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
return (new Socket(s, domainnum, typenum, protonum));
|
||||
}
|
75
io/socket/socket.h
Normal file
75
io/socket/socket.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2012 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef IO_SOCKET_SOCKET_H
|
||||
#define IO_SOCKET_SOCKET_H
|
||||
|
||||
#include <event/action.h>
|
||||
#include <event/event_callback.h>
|
||||
#include <event/typed_pair_callback.h>
|
||||
#include <io/stream_handle.h>
|
||||
#include <io/socket/socket_types.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: socket.h //
|
||||
// Description: a stream handle for network connections //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef class TypedPairCallback<Event, Socket*> SocketEventCallback;
|
||||
typedef class CallbackAction<Socket, SocketEventCallback> SocketEventAction;
|
||||
|
||||
class Socket : public StreamHandle
|
||||
{
|
||||
LogHandle log_;
|
||||
int domain_;
|
||||
int socktype_;
|
||||
int protocol_;
|
||||
SocketEventAction* accept_request_;
|
||||
Action* accept_check_;
|
||||
|
||||
private:
|
||||
Socket (int, int, int, int);
|
||||
|
||||
public:
|
||||
Action* accept (SocketEventCallback*);
|
||||
void accept_complete (Event);
|
||||
void accept_cancel ();
|
||||
Action* connect (const std::string&, EventCallback*);
|
||||
bool bind (const std::string&);
|
||||
bool listen ();
|
||||
bool shutdown (bool, bool);
|
||||
|
||||
std::string getpeername () const;
|
||||
std::string getsockname () const;
|
||||
|
||||
static Socket* create (SocketAddressFamily, SocketType, const std::string& = "", const std::string& = "");
|
||||
};
|
||||
|
||||
#endif /* !IO_SOCKET_SOCKET_H */
|
44
io/socket/socket_types.h
Normal file
44
io/socket/socket_types.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2011 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef IO_SOCKET_SOCKET_TYPES_H
|
||||
#define IO_SOCKET_SOCKET_TYPES_H
|
||||
|
||||
enum SocketAddressFamily {
|
||||
SocketAddressFamilyIP,
|
||||
SocketAddressFamilyIPv4,
|
||||
SocketAddressFamilyIPv6,
|
||||
SocketAddressFamilyUnix,
|
||||
SocketAddressFamilyUnspecified
|
||||
};
|
||||
|
||||
enum SocketType {
|
||||
SocketTypeStream,
|
||||
SocketTypeDatagram,
|
||||
};
|
||||
|
||||
class Socket;
|
||||
|
||||
#endif /* !IO_SOCKET_SOCKET_TYPES_H */
|
64
io/socket/unix_server.cc
Normal file
64
io/socket/unix_server.cc
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2012 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <io/socket/unix_server.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: unix_server.cc //
|
||||
// Description: base class for a UNIX domain server //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool UnixServer::listen (const std::string& name)
|
||||
{
|
||||
if (socket_)
|
||||
{
|
||||
socket_->close (0);
|
||||
delete socket_;
|
||||
}
|
||||
|
||||
socket_ = Socket::create (SocketAddressFamilyUnix, SocketTypeStream);
|
||||
if (! socket_)
|
||||
{
|
||||
ERROR("/unix/server") << "Unable to create socket.";
|
||||
return false;
|
||||
}
|
||||
if (! socket_->bind (name))
|
||||
{
|
||||
ERROR("/unix/server") << "Socket bind failed";
|
||||
return false;
|
||||
}
|
||||
if (! socket_->listen ())
|
||||
{
|
||||
ERROR("/unix/server") << "Socket listen failed";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
68
io/socket/unix_server.h
Normal file
68
io/socket/unix_server.h
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2011 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef IO_SOCKET_UNIX_SERVER_H
|
||||
#define IO_SOCKET_UNIX_SERVER_H
|
||||
|
||||
#include <io/socket/socket.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: unix_server.h //
|
||||
// Description: base class for a UNIX domain server //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class UnixServer
|
||||
{
|
||||
LogHandle log_;
|
||||
Socket* socket_;
|
||||
|
||||
public:
|
||||
UnixServer () : log_("/unix/server"), socket_(0)
|
||||
{ }
|
||||
|
||||
~UnixServer()
|
||||
{
|
||||
delete socket_;
|
||||
}
|
||||
|
||||
bool listen (const std::string& name);
|
||||
|
||||
Action* accept (SocketEventCallback* cb)
|
||||
{
|
||||
return (socket_ ? socket_->accept (cb) : 0);
|
||||
}
|
||||
|
||||
Action* close (EventCallback* cb)
|
||||
{
|
||||
return (socket_ ? socket_->close (cb) : 0);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* !IO_SOCKET_UNIX_SERVER_H */
|
69
io/stream_handle.cc
Normal file
69
io/stream_handle.cc
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2011 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <event/event_system.h>
|
||||
#include <io/stream_handle.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: stream_handle.cc //
|
||||
// Description: basic operations on stream objects //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
StreamHandle::StreamHandle (int fd) : log_("/file/descriptor"), fd_(fd)
|
||||
{
|
||||
int flags = ::fcntl (fd_, F_GETFL, 0);
|
||||
if (flags == -1)
|
||||
ERROR(log_) << "Could not get flags for file descriptor.";
|
||||
else
|
||||
{
|
||||
flags = ::fcntl (fd_, F_SETFL, flags | O_NONBLOCK);
|
||||
if (flags == -1)
|
||||
ERROR(log_) << "Could not set flags for file descriptor, some operations may block.";
|
||||
}
|
||||
}
|
||||
|
||||
Action* StreamHandle::read (EventCallback* cb)
|
||||
{
|
||||
return event_system.track (fd_, StreamModeRead, cb);
|
||||
}
|
||||
|
||||
Action* StreamHandle::write (Buffer& buf, EventCallback* cb)
|
||||
{
|
||||
if (cb)
|
||||
cb->param ().buffer_ = buf;
|
||||
|
||||
return event_system.track (fd_, StreamModeWrite, cb);
|
||||
}
|
||||
|
||||
Action* StreamHandle::close (EventCallback* cb)
|
||||
{
|
||||
return event_system.track (fd_, StreamModeEnd, cb);
|
||||
}
|
54
io/stream_handle.h
Normal file
54
io/stream_handle.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2011 Juli Mallett. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef IO_STREAM_HANDLE_H
|
||||
#define IO_STREAM_HANDLE_H
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// File: stream_handle.h //
|
||||
// Description: basic operations on stream objects //
|
||||
// Project: WANProxy XTech //
|
||||
// Adapted by: Andreu Vidal Bramfeld-Software //
|
||||
// Last modified: 2015-04-01 //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class StreamHandle
|
||||
{
|
||||
LogHandle log_;
|
||||
protected:
|
||||
int fd_;
|
||||
|
||||
public:
|
||||
StreamHandle (int);
|
||||
virtual ~StreamHandle () {}
|
||||
|
||||
virtual Action* read (EventCallback* cb);
|
||||
virtual Action* write (Buffer& buf, EventCallback* cb);
|
||||
virtual Action* close (EventCallback* cb = 0);
|
||||
};
|
||||
|
||||
#endif /* !IO_STREAM_HANDLE_H */
|
Loading…
Add table
Add a link
Reference in a new issue