Changeset - r25826:89dc24729f74
[Not reviewed]
master
0 2 0
Patric Stout - 3 years ago 2021-04-28 08:55:35
truebrain@openttd.org
Codechange: allow Connect() to bind to a local address
2 files changed with 16 insertions and 4 deletions:
0 comments (0 inline, 0 general)
src/network/core/tcp.h
Show inline comments
 
@@ -95,12 +95,13 @@ private:
 
	size_t current_address = 0;                         ///< Current index in addresses we are trying.
 

	
 
	std::vector<SOCKET> sockets;                        ///< Pending connect() attempts.
 
	std::chrono::steady_clock::time_point last_attempt; ///< Time we last tried to connect.
 

	
 
	std::string connection_string;                      ///< Current address we are connecting to (before resolving).
 
	NetworkAddress bind_address;                        ///< Address we're binding to, if any.
 

	
 
	void Resolve();
 
	void OnResolved(addrinfo *ai);
 
	bool TryNextAddress();
 
	void Connect(addrinfo *address);
 
	virtual bool CheckActivity();
 
@@ -110,13 +111,13 @@ private:
 
	friend class TCPServerConnecter;
 

	
 
	static void ResolveThunk(TCPConnecter *connecter);
 

	
 
public:
 
	TCPConnecter() {};
 
	TCPConnecter(const std::string &connection_string, uint16 default_port);
 
	TCPConnecter(const std::string &connection_string, uint16 default_port, NetworkAddress bind_address = {});
 
	virtual ~TCPConnecter();
 

	
 
	/**
 
	 * Callback when the connection succeeded.
 
	 * @param s the socket that we opened
 
	 */
src/network/core/tcp_connect.cpp
Show inline comments
 
@@ -21,16 +21,19 @@
 
#include "../../safeguards.h"
 

	
 
/** List of connections that are currently being created */
 
static std::vector<TCPConnecter *> _tcp_connecters;
 

	
 
/**
 
 * Create a new connecter for the given address
 
 * @param connection_string the address to connect to
 
 * Create a new connecter for the given address.
 
 * @param connection_string The address to connect to.
 
 * @param default_port If not indicated in connection_string, what port to use.
 
 * @param bind_address The local bind address to use. Defaults to letting the OS find one.
 
 */
 
TCPConnecter::TCPConnecter(const std::string &connection_string, uint16 default_port)
 
TCPConnecter::TCPConnecter(const std::string &connection_string, uint16 default_port, NetworkAddress bind_address) :
 
	bind_address(bind_address)
 
{
 
	this->connection_string = NormalizeConnectionString(connection_string, default_port);
 

	
 
	_tcp_connecters.push_back(this);
 
}
 

	
 
@@ -93,12 +96,20 @@ void TCPConnecter::Connect(addrinfo *add
 
	SOCKET sock = socket(address->ai_family, address->ai_socktype, address->ai_protocol);
 
	if (sock == INVALID_SOCKET) {
 
		Debug(net, 0, "Could not create {} {} socket: {}", NetworkAddress::SocketTypeAsString(address->ai_socktype), NetworkAddress::AddressFamilyAsString(address->ai_family), NetworkError::GetLast().AsString());
 
		return;
 
	}
 

	
 
	if (this->bind_address.GetPort() > 0) {
 
		if (bind(sock, (const sockaddr *)this->bind_address.GetAddress(), this->bind_address.GetAddressLength()) != 0) {
 
			Debug(net, 1, "Could not bind socket on {}: {}", this->bind_address.GetAddressAsString(), NetworkError::GetLast().AsString());
 
			closesocket(sock);
 
			return;
 
		}
 
	}
 

	
 
	if (!SetNoDelay(sock)) {
 
		Debug(net, 1, "Setting TCP_NODELAY failed: {}", NetworkError::GetLast().AsString());
 
	}
 
	if (!SetNonBlocking(sock)) {
 
		Debug(net, 0, "Setting non-blocking mode failed: {}", NetworkError::GetLast().AsString());
 
	}
0 comments (0 inline, 0 general)