summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/socket.h7
-rw-r--r--include/socketengine.h37
-rw-r--r--src/dns.cpp5
-rw-r--r--src/listensocket.cpp3
-rw-r--r--src/socket.cpp50
-rw-r--r--src/socketengine.cpp12
6 files changed, 41 insertions, 73 deletions
diff --git a/include/socket.h b/include/socket.h
index b012cf62a..6a0cc88ad 100644
--- a/include/socket.h
+++ b/include/socket.h
@@ -96,13 +96,6 @@ namespace irc
*/
CoreExport bool MatchCIDR(const std::string &address, const std::string &cidr_mask, bool match_with_username);
- /** Create a new valid file descriptor using socket()
- * @return On return this function will return a value >= 0 for success,
- * or a negative value upon failure (negative values are invalid file
- * descriptors)
- */
- CoreExport int OpenTCPSocket(const std::string& addr, int socktype = SOCK_STREAM);
-
/** Return the size of the structure for syscall passing */
inline int sa_size(const irc::sockets::sockaddrs& sa) { return sa.sa_size(); }
diff --git a/include/socketengine.h b/include/socketengine.h
index 662bd8e05..e0512b3aa 100644
--- a/include/socketengine.h
+++ b/include/socketengine.h
@@ -62,7 +62,7 @@ enum EventMask
* it may not require a system call to transition from FD_WANT_FAST_READ
*/
FD_WANT_EDGE_READ = 0x8,
-
+
/** Mask for all read events */
FD_WANT_READ_MASK = 0x0F,
@@ -362,100 +362,97 @@ public:
* @param fd This version of the call takes an EventHandler instead of a bare file descriptor.
* @return This method should return exactly the same values as the system call it emulates.
*/
- virtual int Accept(EventHandler* fd, sockaddr *addr, socklen_t *addrlen);
+ int Accept(EventHandler* fd, sockaddr *addr, socklen_t *addrlen);
/** Abstraction for BSD sockets close(2).
* This function should emulate its namesake system call exactly.
* @param fd This version of the call takes an EventHandler instead of a bare file descriptor.
* @return This method should return exactly the same values as the system call it emulates.
*/
- virtual int Close(EventHandler* fd);
+ int Close(EventHandler* fd);
/** Abstraction for BSD sockets close(2).
* This function should emulate its namesake system call exactly.
* This function should emulate its namesake system call exactly.
* @return This method should return exactly the same values as the system call it emulates.
*/
- virtual int Close(int fd);
+ int Close(int fd);
/** Abstraction for BSD sockets send(2).
* This function should emulate its namesake system call exactly.
* @param fd This version of the call takes an EventHandler instead of a bare file descriptor.
* @return This method should return exactly the same values as the system call it emulates.
*/
- virtual int Send(EventHandler* fd, const void *buf, size_t len, int flags);
+ int Send(EventHandler* fd, const void *buf, size_t len, int flags);
/** Abstraction for BSD sockets recv(2).
* This function should emulate its namesake system call exactly.
* @param fd This version of the call takes an EventHandler instead of a bare file descriptor.
* @return This method should return exactly the same values as the system call it emulates.
*/
- virtual int Recv(EventHandler* fd, void *buf, size_t len, int flags);
+ int Recv(EventHandler* fd, void *buf, size_t len, int flags);
/** Abstraction for BSD sockets recvfrom(2).
* This function should emulate its namesake system call exactly.
* @param fd This version of the call takes an EventHandler instead of a bare file descriptor.
* @return This method should return exactly the same values as the system call it emulates.
*/
- virtual int RecvFrom(EventHandler* fd, void *buf, size_t len, int flags, sockaddr *from, socklen_t *fromlen);
+ int RecvFrom(EventHandler* fd, void *buf, size_t len, int flags, sockaddr *from, socklen_t *fromlen);
/** Abstraction for BSD sockets sendto(2).
* This function should emulate its namesake system call exactly.
* @param fd This version of the call takes an EventHandler instead of a bare file descriptor.
* @return This method should return exactly the same values as the system call it emulates.
*/
- virtual int SendTo(EventHandler* fd, const void *buf, size_t len, int flags, const sockaddr *to, socklen_t tolen);
+ int SendTo(EventHandler* fd, const void *buf, size_t len, int flags, const sockaddr *to, socklen_t tolen);
/** Abstraction for BSD sockets connect(2).
* This function should emulate its namesake system call exactly.
* @param fd This version of the call takes an EventHandler instead of a bare file descriptor.
* @return This method should return exactly the same values as the system call it emulates.
*/
- virtual int Connect(EventHandler* fd, const sockaddr *serv_addr, socklen_t addrlen);
+ int Connect(EventHandler* fd, const sockaddr *serv_addr, socklen_t addrlen);
/** Make a file descriptor blocking.
* @param fd a file descriptor to set to blocking mode
* @return 0 on success, -1 on failure, errno is set appropriately.
*/
- virtual int Blocking(int fd);
+ int Blocking(int fd);
/** Make a file descriptor nonblocking.
* @param fd A file descriptor to set to nonblocking mode
* @return 0 on success, -1 on failure, errno is set appropriately.
*/
- virtual int NonBlocking(int fd);
+ int NonBlocking(int fd);
/** Abstraction for BSD sockets shutdown(2).
* This function should emulate its namesake system call exactly.
* @param fd This version of the call takes an EventHandler instead of a bare file descriptor.
* @return This method should return exactly the same values as the system call it emulates.
*/
- virtual int Shutdown(EventHandler* fd, int how);
+ int Shutdown(EventHandler* fd, int how);
/** Abstraction for BSD sockets shutdown(2).
* This function should emulate its namesake system call exactly.
* @return This method should return exactly the same values as the system call it emulates.
*/
- virtual int Shutdown(int fd, int how);
+ int Shutdown(int fd, int how);
/** Abstraction for BSD sockets bind(2).
* This function should emulate its namesake system call exactly.
* @return This method should return exactly the same values as the system call it emulates.
*/
- virtual int Bind(int fd, const sockaddr *my_addr, socklen_t addrlen);
+ int Bind(int fd, const sockaddr *my_addr, socklen_t addrlen);
/** Abstraction for BSD sockets listen(2).
* This function should emulate its namesake system call exactly.
* @return This method should return exactly the same values as the system call it emulates.
*/
- virtual int Listen(int sockfd, int backlog);
+ int Listen(int sockfd, int backlog);
- /** Abstraction for BSD sockets getsockname(2).
- * This function should emulate its namesake system call exactly.
- * @param fd This version of the call takes an EventHandler instead of a bare file descriptor.
- * @return This method should return exactly the same values as the system call it emulates.
+ /** Set SO_REUSEADDR and SO_LINGER on this file descriptor
*/
- virtual int GetSockName(EventHandler* fd, sockaddr *name, socklen_t* namelen);
+ void SetReuse(int sockfd);
/** This function is called immediately after fork().
* Some socket engines (notably kqueue) cannot have their
diff --git a/src/dns.cpp b/src/dns.cpp
index 7be0f6874..80909c0bb 100644
--- a/src/dns.cpp
+++ b/src/dns.cpp
@@ -306,13 +306,14 @@ void DNS::Rehash()
irc::sockets::aptosa(ServerInstance->Config->DNSServer, DNS::QUERY_PORT, myserver);
/* Initialize mastersocket */
- int s = irc::sockets::OpenTCPSocket(ServerInstance->Config->DNSServer, SOCK_DGRAM);
+ int s = socket(myserver.sa.sa_family, SOCK_DGRAM, 0);
this->SetFd(s);
- ServerInstance->SE->NonBlocking(this->GetFd());
/* Have we got a socket and is it nonblocking? */
if (this->GetFd() != -1)
{
+ ServerInstance->SE->SetReuse(s);
+ ServerInstance->SE->NonBlocking(s);
/* Bind the port - port 0 INADDR_ANY */
if (!ServerInstance->BindSocket(this->GetFd(), portpass, "", false))
{
diff --git a/src/listensocket.cpp b/src/listensocket.cpp
index 43584eae1..676898647 100644
--- a/src/listensocket.cpp
+++ b/src/listensocket.cpp
@@ -31,10 +31,11 @@ ListenSocket::ListenSocket(ConfigTag* tag, const std::string& addr, int port)
irc::sockets::satoap(bind_to, bind_addr, bind_port);
bind_desc = irc::sockets::satouser(bind_to);
- fd = irc::sockets::OpenTCPSocket(bind_addr);
+ fd = socket(bind_to.sa.sa_family, SOCK_STREAM, 0);
if (this->fd > -1)
{
+ ServerInstance->SE->SetReuse(fd);
int rv = ServerInstance->SE->Bind(this->fd, &bind_to.sa, sizeof(bind_to));
if (rv >= 0)
rv = ServerInstance->SE->Listen(this->fd, ServerInstance->Config->MaxConn);
diff --git a/src/socket.cpp b/src/socket.cpp
index ef81542e1..eb47c9cc8 100644
--- a/src/socket.cpp
+++ b/src/socket.cpp
@@ -66,40 +66,6 @@ bool InspIRCd::BindSocket(int sockfd, int port, const char* addr, bool dolisten)
}
}
-// Open a TCP Socket
-int irc::sockets::OpenTCPSocket(const std::string& addr, int socktype)
-{
- int sockfd;
- int on = 1;
- struct linger linger = { 0, 0 };
- if (addr.empty())
- {
-#ifdef IPV6
- sockfd = socket (PF_INET6, socktype, 0);
- if (sockfd < 0)
-#endif
- sockfd = socket (PF_INET, socktype, 0);
- }
- else if (addr.find(':') != std::string::npos)
- sockfd = socket (PF_INET6, socktype, 0);
- else
- sockfd = socket (PF_INET, socktype, 0);
-
- if (sockfd < 0)
- {
- return ERROR;
- }
- else
- {
- setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on));
- /* This is BSD compatible, setting l_onoff to 0 is *NOT* http://web.irc.org/mla/ircd-dev/msg02259.html */
- linger.l_onoff = 1;
- linger.l_linger = 1;
- setsockopt(sockfd, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(linger));
- return (sockfd);
- }
-}
-
int InspIRCd::BindPorts(FailedPortList &failed_ports)
{
int bound = 0;
@@ -112,7 +78,7 @@ int InspIRCd::BindPorts(FailedPortList &failed_ports)
std::string porttag = tag->getString("port");
std::string Addr = tag->getString("address");
- if (strncmp(Addr.c_str(), "::ffff:", 7) == 0)
+ if (strncasecmp(Addr.c_str(), "::ffff:", 7) == 0)
this->Logs->Log("SOCKET",DEFAULT, "Using 4in6 (::ffff:) isn't recommended. You should bind IPv4 addresses directly instead.");
irc::portparser portrange(porttag, false);
@@ -175,7 +141,7 @@ int InspIRCd::BindPorts(FailedPortList &failed_ports)
bool irc::sockets::aptosa(const std::string& addr, int port, irc::sockets::sockaddrs& sa)
{
memset(&sa, 0, sizeof(sa));
- if (addr.empty())
+ if (addr.empty() || addr.c_str()[0] == '*')
{
#ifdef IPV6
sa.in6.sin6_family = AF_INET6;
@@ -242,11 +208,13 @@ std::string irc::sockets::sockaddrs::str() const
char buffer[MAXBUF];
if (sa.sa_family == AF_INET)
{
+#ifndef IPV6
if (in4.sin_addr.s_addr == 0)
{
sprintf(buffer, "*:%u", ntohs(in4.sin_port));
}
else
+#endif
{
const uint8_t* bits = reinterpret_cast<const uint8_t*>(&in4.sin_addr);
sprintf(buffer, "%d.%d.%d.%d:%u", bits[0], bits[1], bits[2], bits[3], ntohs(in4.sin_port));
@@ -254,11 +222,13 @@ std::string irc::sockets::sockaddrs::str() const
}
else if (sa.sa_family == AF_INET6)
{
+#ifdef IPV6
if (!memcmp(all_zero, &in6.sin6_addr, 16))
{
sprintf(buffer, "*:%u", ntohs(in6.sin6_port));
}
else
+#endif
{
buffer[0] = '[';
if (!inet_ntop(AF_INET6, &in6.sin6_addr, buffer+1, MAXBUF - 10))
@@ -282,7 +252,7 @@ int irc::sockets::sockaddrs::sa_size() const
return 0;
}
-static void sa2cidr(const irc::sockets::sockaddrs& sa, irc::sockets::cidr_mask& cidr, int range)
+static void sa2cidr(irc::sockets::cidr_mask& cidr, const irc::sockets::sockaddrs& sa, int range)
{
const unsigned char* base;
cidr.type = sa.sa.sa_family;
@@ -319,7 +289,7 @@ static void sa2cidr(const irc::sockets::sockaddrs& sa, irc::sockets::cidr_mask&
irc::sockets::cidr_mask::cidr_mask(const irc::sockets::sockaddrs& sa, int range)
{
- sa2cidr(sa, *this, range);
+ sa2cidr(*this, sa, range);
}
irc::sockets::cidr_mask::cidr_mask(const std::string& mask)
@@ -330,13 +300,13 @@ irc::sockets::cidr_mask::cidr_mask(const std::string& mask)
if (bits_chars == std::string::npos)
{
irc::sockets::aptosa(mask, 0, sa);
- sa2cidr(sa, *this, 128);
+ sa2cidr(*this, sa, 128);
}
else
{
int range = atoi(mask.substr(bits_chars + 1).c_str());
irc::sockets::aptosa(mask.substr(0, bits_chars), 0, sa);
- sa2cidr(sa, *this, range);
+ sa2cidr(*this, sa, range);
}
}
diff --git a/src/socketengine.cpp b/src/socketengine.cpp
index 2dbc82b27..478400d1b 100644
--- a/src/socketengine.cpp
+++ b/src/socketengine.cpp
@@ -152,9 +152,15 @@ int SocketEngine::NonBlocking(int fd)
#endif
}
-int SocketEngine::GetSockName(EventHandler* fd, sockaddr *name, socklen_t* namelen)
-{
- return getsockname(fd->GetFd(), name, namelen);
+void SocketEngine::SetReuse(int fd)
+{
+ int on = 1;
+ struct linger linger = { 0, 0 };
+ setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on));
+ /* This is BSD compatible, setting l_onoff to 0 is *NOT* http://web.irc.org/mla/ircd-dev/msg02259.html */
+ linger.l_onoff = 1;
+ linger.l_linger = 1;
+ setsockopt(fd, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(linger));
}
int SocketEngine::RecvFrom(EventHandler* fd, void *buf, size_t len, int flags, sockaddr *from, socklen_t *fromlen)