New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Does not use bind to local address for outgoing connections #6476
Comments
Right, there is no option to specify binding for outgoing connections. |
I don't care about things like DNS, I would just like the bitcoin traffic itself to go over the addresses I select. |
Seems reasonable to implement.
|
Has this been implemented ? If not is there a timeframe for it ? |
@phatkiller: The issue is still open that's a sign that nobody has implemented it right now. We don't have a timeframe for features. Bitcoin-Core is an open source project, it will only be implemented if someone invests time to implement a such feature (which mostly is a sign that someone requires that feature). |
If you need this, you need to make sure it gets implemented yourself. This is not a place to get free (as in beer) development resources. |
What is required is to bind the socket to the -bind address prior to connecting to the remote site, not the usual way this would be done. I've looked at the code in net.cpp and netbase.cpp and boost appears to be in use and the location of the -bind ip constant is not obvious to me. I'm not skilled with c++. Here's a rough outline of what needs to be done but I don't have the skill to do it in the cpp environment. Perhaps someone else will pick up this thread. Found this doing research on the issue. int sockfd = socket(AF_INET, SOCK_STREAM, 0); |
This seems like an unusual request. Do you need bitcoin to use different outgoing IP address than other applications on the system? Or to connect from a different IP address than it it listens on? If not, it seems like you could be better off just fixing the routing table: https://serverfault.com/questions/182550/specifing-ip-address-for-outbound-connections-on-a-multi-ip-host |
This can't be fixed through a routing table because it's not about return packets for incoming connections but for packets that are for connections initiated by the process itself, which if not bindable to a specific IP (as per this request) will just use the hosts' default IP (which may not be the IP where incoming packets arrive). So not that unusual of a request, I had to dockerize and apply some iptables magic to make this work right on a node with multiple IPs within the same subnet. |
I feel that this is needed for avoiding mess up with IPv6 privacy randomized addresses. |
This request looks reasonable. Is there still interest in it? Something like this should do it (and pass the proper argument to -bool ConnectSocketDirectly(const CService &addrConnect, const Sock& sock, int nTimeout, bool manual_connection)
+bool ConnectSocketDirectly(const std::optional<CNetAddr>& addr_from, const CService &addrConnect, const Sock& sock, int nTimeout, bool manual_connection)
{
// Create a sockaddr from the specified service.
struct sockaddr_storage sockaddr;
socklen_t len = sizeof(sockaddr);
if (sock.Get() == INVALID_SOCKET) {
LogPrintf("Cannot connect to %s: invalid socket\n", addrConnect.ToStringAddrPort());
return false;
}
if (!addrConnect.GetSockAddr((struct sockaddr*)&sockaddr, &len)) {
LogPrintf("Cannot connect to %s: unsupported network\n", addrConnect.ToStringAddrPort());
return false;
}
+ if (addr_from.has_value()) {
+ struct sockaddr_storage storage;
+ struct sockaddr* saddr_from = reinterpret_cast<struct sockaddr*>(&storage);
+ socklen_t saddr_from_len = sizeof(storage);
+ if (!CService{addr_from.value(), /*port=*/0}.GetSockAddr(saddr_from, &saddr_from_len)) {
+ LogPrintLevel(
+ BCLog::NET,
+ BCLog::Level::Error,
+ "Cannot connect to %s: unsupported network of the specified outbound address %s\n",
+ addrConnect.ToStringAddrPort(),
+ addr_from->ToStringAddr());
+ return false;
+ }
+ if (sock.Bind(saddr_from, saddr_from_len) == SOCKET_ERROR) {
+ LogPrintLevel(
+ BCLog::NET,
+ BCLog::Level::Error,
+ "Cannot connect to %s: unable to bind to the specified outbound address %s: %s\n",
+ addrConnect.ToStringAddrPort(),
+ addr_from->ToStringAddr(),
+ NetworkErrorString(WSAGetLastError()));
+ return false;
+ }
+ }
+
// Connect to the addrConnect service on the hSocket socket.
if (sock.Connect(reinterpret_cast<struct sockaddr*>(&sockaddr), len) == SOCKET_ERROR) { |
Well, I still interested in it. It is a logical thing to do in general. |
I have several IPv4 / IPv6 addresses on a host and I wish to use a specific one. So I set up the bind so it would use that. It seems to be using that for the bind() in the listen socket but not for the outgoing connections.
I've tried settings externalip. That only seems to change the "localaddresses" returned by getnetworkinfo. I'm guessing that's mostly useful for NAT.
The text was updated successfully, but these errors were encountered: