diff --git a/Net/include/Poco/Net/DatagramSocket.h b/Net/include/Poco/Net/DatagramSocket.h index e25a16b0c..93ba3505a 100644 --- a/Net/include/Poco/Net/DatagramSocket.h +++ b/Net/include/Poco/Net/DatagramSocket.h @@ -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. diff --git a/Net/include/Poco/Net/RawSocket.h b/Net/include/Poco/Net/RawSocket.h index 43efd7a95..75b62bfbb 100644 --- a/Net/include/Poco/Net/RawSocket.h +++ b/Net/include/Poco/Net/RawSocket.h @@ -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. diff --git a/Net/include/Poco/Net/ServerSocket.h b/Net/include/Poco/Net/ServerSocket.h index 2fb7727a0..aeddcff5a 100644 --- a/Net/include/Poco/Net/ServerSocket.h +++ b/Net/include/Poco/Net/ServerSocket.h @@ -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. /// diff --git a/Net/include/Poco/Net/SocketImpl.h b/Net/include/Poco/Net/SocketImpl.h index 533332e6c..217da21af 100644 --- a/Net/include/Poco/Net/SocketImpl.h +++ b/Net/include/Poco/Net/SocketImpl.h @@ -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. /// diff --git a/Net/include/Poco/Net/WebSocketImpl.h b/Net/include/Poco/Net/WebSocketImpl.h index 060bc8a67..fc1135dcc 100644 --- a/Net/include/Poco/Net/WebSocketImpl.h +++ b/Net/include/Poco/Net/WebSocketImpl.h @@ -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(); diff --git a/Net/src/DatagramSocket.cpp b/Net/src/DatagramSocket.cpp index ce5d6b7ee..a7acbd480 100644 --- a/Net/src/DatagramSocket.cpp +++ b/Net/src/DatagramSocket.cpp @@ -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); diff --git a/Net/src/RawSocket.cpp b/Net/src/RawSocket.cpp index 2f35c3027..641ad158e 100644 --- a/Net/src/RawSocket.cpp +++ b/Net/src/RawSocket.cpp @@ -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); diff --git a/Net/src/ServerSocket.cpp b/Net/src/ServerSocket.cpp index d52e5977a..ca86fce36 100644 --- a/Net/src/ServerSocket.cpp +++ b/Net/src/ServerSocket.cpp @@ -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); diff --git a/Net/src/SocketImpl.cpp b/Net/src/SocketImpl.cpp index 1357b3501..02dcdda9c 100644 --- a/Net/src/SocketImpl.cpp +++ b/Net/src/SocketImpl.cpp @@ -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 diff --git a/Net/src/WebSocketImpl.cpp b/Net/src/WebSocketImpl.cpp index 760a75061..d1c72d843 100644 --- a/Net/src/WebSocketImpl.cpp +++ b/Net/src/WebSocketImpl.cpp @@ -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");