I have a Debian/linux server which has several Ip adresses, all assigned to the same physical network card. The /etc/network/interfaces
config file looks like this (the xx represent numbers)
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
address 176.xx.xx.144
netmask 255.255.255.0
network 176.xx.xx.0
broadcast 176.xx.xx.255
gateway 176.xx.xx.254
auto eth0:0
allow-hotplug eth0:0
iface eth0:0 inet static
address 46.xx.xx.57
netmask 255.255.255.255
broadcast 46.xx.xx.57
auto eth0:1
allow-hotplug eth0:1
iface eth0:1 inet static
address 94.xx.xx.166
netmask 255.255.255.255
broadcast 94.xx.xx.166
//IPv6 Stuff...
I am working on a client application that uses Boost Asio to handle all network connections. In this Application I want to be able to connect to an external server using a specific networkinterface/Ip address. I found this similar question, however simply binding a boost::asio::ip::tcp::socket
to a specfic endpoint and then connect to an external Server doesn't work. Here is a minimal working example of what I tried:
#include <iostream>
#include <boost/asio.hpp>
int main( int argC, char *argV[] ) {
boost::asio::io_service ioService;
boost::asio::ip::tcp::socket socket(ioService);
boost::asio::ip::tcp::endpoint localEndpoint(
boost::asio::ip::address::from_string("94.xx.xx.166"), 0);
boost::asio::ip::tcp::resolver resolver(ioService);
boost::asio::ip::tcp::resolver::iterator remoteEndpoint =
resolver.resolve(boost::asio::ip::tcp::resolver::query("haatschii.de", "80"));
socket.open(boost::asio::ip::tcp::v4());
std::cout << "Before binding socket has local endpoint: "
<< socket.local_endpoint().address().to_string()
<< ":" << socket.local_endpoint().port() << std::endl;
socket.bind(localEndpoint);
std::cout << "Before connecting socket has local endpoint: "
<< socket.local_endpoint().address().to_string()
<< ":" << socket.local_endpoint().port() << std::endl;
boost::asio::connect(socket, remoteEndpoint);
std::cout << "After connecting socket has local endpoint: "
<< socket.local_endpoint().address().to_string()
<< ":" << socket.local_endpoint().port() << std::endl;
//Test request to a page that echos our IP address.
boost::asio::write(socket,
boost::asio::buffer("GET /ip.php HTTP/1.1\r\nHost: haatschii.de\r\nAccept: */*\r\n\r\n", 57));
//Parse server response (not important for this code example)
return 0;
}
When I run this on my server I get:
Before binding socket has local endpoint: 0.0.0.0:0
Before connecting socket has local endpoint: 94.xx.xx.166:38399
After connecting socket has local endpoint: 176.xx.xx.144:45959
External server says we are using IP: 176.xx.xx.144
Right now I am a bit lost, because I don't know what else to try. I don't necessarily need a portable solution for this, anything that works with this Debian setup will do.
Update
I'll offer the bounty for a solution that works for my setup. If necessary I can change the /etc/network/interfaces
config file. However in order to reuse my code, any solution has to work with Boost Asio sockets (at least as a wrapper).