mirror of
https://github.com/pocoproject/poco.git
synced 2025-01-20 18:00:05 +01:00
Add a new bind() and bind6() interface and make REUSEPORT as an option.
SO_REUSEADDR is to reuse a socket in time-wait state, this is often turned on by server applicationis, but if a port is being used, the server could fail, this is expected. But with SO_REUSEPORT option, it even can open a port which is being used, this is a more error prone than SO_REUSEADDR, because we normally don't want to share a port with irrelevant application without notice, the behavior should not be default.
This commit is contained in:
parent
efdeadef2a
commit
0ad635c5d4
@ -89,6 +89,20 @@ public:
|
||||
///
|
||||
/// Calls to connect cannot() come before calls to bind().
|
||||
|
||||
void bind(const SocketAddress& address, bool reuseAddress, bool reusePort);
|
||||
/// Bind a local address to the socket.
|
||||
///
|
||||
/// This is usually only done when establishing a server
|
||||
/// socket.
|
||||
///
|
||||
/// If reuseAddress is true, sets the SO_REUSEADDR
|
||||
/// socket option.
|
||||
///
|
||||
/// If reusePort is true, sets the SO_REUSEPORT
|
||||
/// socket option.
|
||||
///
|
||||
/// Calls to connect cannot() come before calls to bind().
|
||||
|
||||
int sendBytes(const void* buffer, int length, int flags = 0);
|
||||
/// Sends the contents of the given buffer through
|
||||
/// the socket.
|
||||
|
@ -82,6 +82,20 @@ public:
|
||||
///
|
||||
/// Calls to connect() cannot come before calls to bind().
|
||||
|
||||
void bind(const SocketAddress& address, bool reuseAddress, bool reusePort);
|
||||
/// Bind a local address to the socket.
|
||||
///
|
||||
/// This is usually only done when establishing a server
|
||||
/// socket.
|
||||
///
|
||||
/// If reuseAddress is true, sets the SO_REUSEADDR
|
||||
/// socket option.
|
||||
///
|
||||
/// If reusePort is true, sets the SO_REUSEPORT
|
||||
/// socket option.
|
||||
///
|
||||
/// Calls to connect() cannot come before calls to bind().
|
||||
|
||||
int sendBytes(const void* buffer, int length, int flags = 0);
|
||||
/// Sends the contents of the given buffer through
|
||||
/// the socket.
|
||||
|
@ -82,6 +82,19 @@ public:
|
||||
/// If reuseAddress is true, sets the SO_REUSEADDR
|
||||
/// socket option.
|
||||
|
||||
virtual void bind(const SocketAddress& address, bool reuseAddress, bool reusePort);
|
||||
/// Binds a local address to the socket.
|
||||
///
|
||||
/// This is usually only done when establishing a server
|
||||
/// socket. TCP clients should not bind a socket to a
|
||||
/// specific address.
|
||||
///
|
||||
/// If reuseAddress is true, sets the SO_REUSEADDR
|
||||
/// socket option.
|
||||
///
|
||||
/// If reuseAddress is true, sets the SO_REUSEPORT
|
||||
/// socket option.
|
||||
|
||||
virtual void bind(Poco::UInt16 port, bool reuseAddress = false);
|
||||
/// Binds a local port to the socket.
|
||||
///
|
||||
@ -91,6 +104,18 @@ public:
|
||||
/// If reuseAddress is true, sets the SO_REUSEADDR
|
||||
/// socket option.
|
||||
|
||||
virtual void bind(Poco::UInt16 port, bool reuseAddress, bool reusePort);
|
||||
/// Binds a local port to the socket.
|
||||
///
|
||||
/// This is usually only done when establishing a server
|
||||
/// socket.
|
||||
///
|
||||
/// If reuseAddress is true, sets the SO_REUSEADDR
|
||||
/// socket option.
|
||||
///
|
||||
/// If reusePort is true, sets the SO_REUSEPORT
|
||||
/// socket option.
|
||||
|
||||
virtual void bind6(const SocketAddress& address, bool reuseAddress = false, bool ipV6Only = false);
|
||||
/// Binds a local IPv6 address to the socket.
|
||||
///
|
||||
@ -108,6 +133,26 @@ public:
|
||||
/// If the library has not been built with IPv6 support,
|
||||
/// a Poco::NotImplementedException will be thrown.
|
||||
|
||||
virtual void bind6(const SocketAddress& address, bool reuseAddress, bool reusePort, bool ipV6Only);
|
||||
/// Binds a local IPv6 address to the socket.
|
||||
///
|
||||
/// This is usually only done when establishing a server
|
||||
/// socket. TCP clients should not bind a socket to a
|
||||
/// specific address.
|
||||
///
|
||||
/// If reuseAddress is true, sets the SO_REUSEADDR
|
||||
/// socket option.
|
||||
///
|
||||
/// If reusePort is true, sets the SO_REUSEPORT
|
||||
/// socket option.
|
||||
///
|
||||
/// The given address must be an IPv6 address. The
|
||||
/// IPPROTO_IPV6/IPV6_V6ONLY option is set on the socket
|
||||
/// according to the ipV6Only parameter.
|
||||
///
|
||||
/// If the library has not been built with IPv6 support,
|
||||
/// a Poco::NotImplementedException will be thrown.
|
||||
|
||||
virtual void bind6(Poco::UInt16 port, bool reuseAddress = false, bool ipV6Only = false);
|
||||
/// Binds a local IPv6 port to the socket.
|
||||
///
|
||||
@ -124,6 +169,24 @@ public:
|
||||
/// If the library has not been built with IPv6 support,
|
||||
/// a Poco::NotImplementedException will be thrown.
|
||||
|
||||
virtual void bind6(Poco::UInt16 port, bool reuseAddress, bool reusePort, bool ipV6Only);
|
||||
/// Binds a local IPv6 port to the socket.
|
||||
///
|
||||
/// This is usually only done when establishing a server
|
||||
/// socket.
|
||||
///
|
||||
/// If reuseAddress is true, sets the SO_REUSEADDR
|
||||
/// socket option.
|
||||
///
|
||||
/// If reusePort is true, sets the SO_REUSEPORT
|
||||
/// socket option.
|
||||
/// The given address must be an IPv6 address. The
|
||||
/// IPPROTO_IPV6/IPV6_V6ONLY option is set on the socket
|
||||
/// according to the ipV6Only parameter.
|
||||
///
|
||||
/// If the library has not been built with IPv6 support,
|
||||
/// a Poco::NotImplementedException will be thrown.
|
||||
|
||||
virtual void listen(int backlog = 64);
|
||||
/// Puts the socket into listening state.
|
||||
///
|
||||
|
@ -86,6 +86,19 @@ public:
|
||||
/// If reuseAddress is true, sets the SO_REUSEADDR
|
||||
/// socket option.
|
||||
|
||||
virtual void bind(const SocketAddress& address, bool reuseAddress, bool reusePort );
|
||||
/// Bind a local address to the socket.
|
||||
///
|
||||
/// This is usually only done when establishing a server
|
||||
/// socket. TCP clients should not bind a socket to a
|
||||
/// specific address.
|
||||
///
|
||||
/// If reuseAddress is true, sets the SO_REUSEADDR
|
||||
/// socket option.
|
||||
///
|
||||
/// If reusePort is true, sets the SO_REUSEPORT
|
||||
/// socket option.
|
||||
|
||||
virtual void bind6(const SocketAddress& address, bool reuseAddress = false, bool ipV6Only = false);
|
||||
/// Bind a local IPv6 address to the socket.
|
||||
///
|
||||
@ -103,6 +116,26 @@ public:
|
||||
/// If the library has not been built with IPv6 support,
|
||||
/// a Poco::NotImplementedException will be thrown.
|
||||
|
||||
virtual void bind6(const SocketAddress& address, bool reuseAddress, bool reusePort, bool ipV6Only);
|
||||
/// Bind a local IPv6 address to the socket.
|
||||
///
|
||||
/// This is usually only done when establishing a server
|
||||
/// socket. TCP clients should not bind a socket to a
|
||||
/// specific address.
|
||||
///
|
||||
/// If reuseAddress is true, sets the SO_REUSEADDR
|
||||
/// socket option.
|
||||
///
|
||||
/// If reusePort is true, sets the SO_REUSEPORT
|
||||
/// socket option.
|
||||
///
|
||||
/// The given address must be an IPv6 address. The
|
||||
/// IPPROTO_IPV6/IPV6_V6ONLY option is set on the socket
|
||||
/// according to the ipV6Only parameter.
|
||||
///
|
||||
/// If the library has not been built with IPv6 support,
|
||||
/// a Poco::NotImplementedException will be thrown.
|
||||
|
||||
virtual void listen(int backlog = 64);
|
||||
/// Puts the socket into listening state.
|
||||
///
|
||||
|
@ -52,7 +52,9 @@ public:
|
||||
virtual void connect(const SocketAddress& address, const Poco::Timespan& timeout);
|
||||
virtual void connectNB(const SocketAddress& address);
|
||||
virtual void bind(const SocketAddress& address, bool reuseAddress = false);
|
||||
virtual void bind(const SocketAddress& address, bool reuseAddress, bool reusePort);
|
||||
virtual void bind6(const SocketAddress& address, bool reuseAddress = false, bool ipV6Only = false);
|
||||
virtual void bind6(const SocketAddress& address, bool reuseAddress, bool reusePort, bool ipV6Only);
|
||||
virtual void listen(int backlog = 64);
|
||||
virtual void close();
|
||||
virtual void shutdownReceive();
|
||||
|
@ -83,6 +83,12 @@ void DatagramSocket::bind(const SocketAddress& address, bool reuseAddress)
|
||||
}
|
||||
|
||||
|
||||
void DatagramSocket::bind(const SocketAddress& address, bool reuseAddress, bool reusePort)
|
||||
{
|
||||
impl()->bind(address, reuseAddress, reusePort);
|
||||
}
|
||||
|
||||
|
||||
int DatagramSocket::sendBytes(const void* buffer, int length, int flags)
|
||||
{
|
||||
return impl()->sendBytes(buffer, length, flags);
|
||||
|
@ -86,6 +86,12 @@ void RawSocket::bind(const SocketAddress& address, bool reuseAddress)
|
||||
}
|
||||
|
||||
|
||||
void RawSocket::bind(const SocketAddress& address, bool reuseAddress, bool reusePort)
|
||||
{
|
||||
impl()->bind(address, reuseAddress, reusePort);
|
||||
}
|
||||
|
||||
|
||||
int RawSocket::sendBytes(const void* buffer, int length, int flags)
|
||||
{
|
||||
return impl()->sendBytes(buffer, length, flags);
|
||||
|
@ -80,6 +80,12 @@ void ServerSocket::bind(const SocketAddress& address, bool reuseAddress)
|
||||
}
|
||||
|
||||
|
||||
void ServerSocket::bind(const SocketAddress& address, bool reuseAddress, bool reusePort)
|
||||
{
|
||||
impl()->bind(address, reuseAddress, reusePort);
|
||||
}
|
||||
|
||||
|
||||
void ServerSocket::bind(Poco::UInt16 port, bool reuseAddress)
|
||||
{
|
||||
IPAddress wildcardAddr;
|
||||
@ -88,12 +94,24 @@ void ServerSocket::bind(Poco::UInt16 port, bool reuseAddress)
|
||||
}
|
||||
|
||||
|
||||
void ServerSocket::bind(Poco::UInt16 port, bool reuseAddress, bool reusePort)
|
||||
{
|
||||
IPAddress wildcardAddr;
|
||||
SocketAddress address(wildcardAddr, port);
|
||||
impl()->bind(address, reuseAddress, reusePort);
|
||||
}
|
||||
|
||||
void ServerSocket::bind6(const SocketAddress& address, bool reuseAddress, bool ipV6Only)
|
||||
{
|
||||
impl()->bind6(address, reuseAddress, ipV6Only);
|
||||
}
|
||||
|
||||
|
||||
void ServerSocket::bind6(const SocketAddress& address, bool reuseAddress, bool reusePort, bool ipV6Only)
|
||||
{
|
||||
impl()->bind6(address, reuseAddress, reusePort, ipV6Only);
|
||||
}
|
||||
|
||||
void ServerSocket::bind6(Poco::UInt16 port, bool reuseAddress, bool ipV6Only)
|
||||
{
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
@ -106,6 +124,17 @@ void ServerSocket::bind6(Poco::UInt16 port, bool reuseAddress, bool ipV6Only)
|
||||
}
|
||||
|
||||
|
||||
void ServerSocket::bind6(Poco::UInt16 port, bool reuseAddress, bool reusePort, bool ipV6Only)
|
||||
{
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
IPAddress wildcardAddr(IPAddress::IPv6);
|
||||
SocketAddress address(wildcardAddr, port);
|
||||
impl()->bind6(address, reuseAddress, reusePort, ipV6Only);
|
||||
#else
|
||||
throw Poco::NotImplementedException("No IPv6 support available");
|
||||
#endif // POCO_HAVE_IPv6
|
||||
}
|
||||
|
||||
void ServerSocket::listen(int backlog)
|
||||
{
|
||||
impl()->listen(backlog);
|
||||
|
@ -190,16 +190,21 @@ void SocketImpl::connectNB(const SocketAddress& address)
|
||||
|
||||
|
||||
void SocketImpl::bind(const SocketAddress& address, bool reuseAddress)
|
||||
{
|
||||
bind(address, reuseAddress, true);
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::bind(const SocketAddress& address, bool reuseAddress, bool reusePort)
|
||||
{
|
||||
if (_sockfd == POCO_INVALID_SOCKET)
|
||||
{
|
||||
init(address.af());
|
||||
}
|
||||
if (reuseAddress)
|
||||
{
|
||||
setReuseAddress(true);
|
||||
if (reusePort)
|
||||
setReusePort(true);
|
||||
}
|
||||
#if defined(POCO_VXWORKS)
|
||||
int rc = ::bind(_sockfd, (sockaddr*) address.addr(), address.length());
|
||||
#else
|
||||
@ -210,6 +215,12 @@ void SocketImpl::bind(const SocketAddress& address, bool reuseAddress)
|
||||
|
||||
|
||||
void SocketImpl::bind6(const SocketAddress& address, bool reuseAddress, bool ipV6Only)
|
||||
{
|
||||
bind6(address, reuseAddress, true, ipV6Only);
|
||||
}
|
||||
|
||||
|
||||
void SocketImpl::bind6(const SocketAddress& address, bool reuseAddress, bool reusePort, bool ipV6Only)
|
||||
{
|
||||
#if defined(POCO_HAVE_IPv6)
|
||||
if (address.family() != SocketAddress::IPv6)
|
||||
@ -225,10 +236,9 @@ void SocketImpl::bind6(const SocketAddress& address, bool reuseAddress, bool ipV
|
||||
if (ipV6Only) throw Poco::NotImplementedException("IPV6_V6ONLY not defined.");
|
||||
#endif
|
||||
if (reuseAddress)
|
||||
{
|
||||
setReuseAddress(true);
|
||||
if (reusePort)
|
||||
setReusePort(true);
|
||||
}
|
||||
int rc = ::bind(_sockfd, address.addr(), address.length());
|
||||
if (rc != 0) error(address.toString());
|
||||
#else
|
||||
|
@ -257,12 +257,23 @@ void WebSocketImpl::bind(const SocketAddress& address, bool reuseAddress)
|
||||
}
|
||||
|
||||
|
||||
void WebSocketImpl::bind(const SocketAddress& address, bool reuseAddress, bool reusePort)
|
||||
{
|
||||
throw Poco::InvalidAccessException("Cannot bind() a WebSocketImpl");
|
||||
}
|
||||
|
||||
|
||||
void WebSocketImpl::bind6(const SocketAddress& address, bool reuseAddress, bool ipV6Only)
|
||||
{
|
||||
throw Poco::InvalidAccessException("Cannot bind6() a WebSocketImpl");
|
||||
}
|
||||
|
||||
|
||||
void WebSocketImpl::bind6(const SocketAddress& address, bool reuseAddress, bool reusePort, bool ipV6Only)
|
||||
{
|
||||
throw Poco::InvalidAccessException("Cannot bind6() a WebSocketImpl");
|
||||
}
|
||||
|
||||
void WebSocketImpl::listen(int backlog)
|
||||
{
|
||||
throw Poco::InvalidAccessException("Cannot listen() on a WebSocketImpl");
|
||||
|
Loading…
x
Reference in New Issue
Block a user