Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Boost.Asio wrong local endpoint

code example:

#include "stdafx.h"
#include <boost/asio.hpp>
#include <winsock2.h>
#include <iostream>
#include <string>


int _tmain(int argc, _TCHAR* argv[])
{
    boost::asio::io_service  service;
    auto sock_ = new boost::asio::basic_stream_socket< boost::asio::ip::tcp >(service);
    if(sock_){
        try {
            boost::asio::ip::address_v4 ipa = boost::asio::ip::address_v4::from_string(argv[1]);
            boost::asio::ip::basic_endpoint<  boost::asio::ip::tcp > address(ipa, (unsigned short) atoi(argv[2]));
            sock_->connect(address);
            std::cout<<"connected. local address:"<<sock_->local_endpoint()<<" remote address:"<<sock_->remote_endpoint()<<std::endl;
        } catch (const boost::system::system_error& e)
        {
            std::cout<<"ERROR:"<<e.what();
        }
    }
    int dummy;
    std::cin>>dummy;
    return 0;
}

I have 2 computers.

  1. output from computer A:connected. local address:XXXXXX remote address:YYYYY (where XXXXX and YYYY real IPs(IPs same to ping output))

  2. output from computer B:connected. local address:127.0.0.1 remote address:YYYYY (where YYYY real IP(IPs same to ping output))

Computer A and B have only 1 NIC
Why I got 127.0.0.1? I cant make real connection from IP 127.0.0.1 to YYYY.
how to fix it?
update:
even windows sockets return 127.0.0.1 on problematic host, see code below

WSADATA wsaData;
auto iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
    return 1;
}
SOCKET ConnectSocket;
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ConnectSocket == INVALID_SOCKET) {

    WSACleanup();
    return 1;
}
sockaddr_in clientService;
clientService.sin_family = AF_INET;

clientService.sin_addr.s_addr = inet_addr(argv[1]);
clientService.sin_port = htons((unsigned short) atoi(argv[2]));
iResult = connect(ConnectSocket, (SOCKADDR *) & clientService, sizeof (clientService));
if (iResult == SOCKET_ERROR) {
    WSACleanup();
    return 1;
}
struct sockaddr_in sin;
int addrlen = sizeof(sin);
if(getsockname(ConnectSocket, (struct sockaddr *)&sin, &addrlen) == 0 &&
   sin.sin_family == AF_INET &&
   addrlen == sizeof(sin))
{
    char *ip = inet_ntoa(sin.sin_addr);
    std::cout<<ip<<std::endl;
}
like image 954
kain64b Avatar asked Oct 12 '15 10:10

kain64b


1 Answers

127.0.0.1 was routed via real NIC :) connection succeeded from 127.0.0.1 to remote ip because of routing :'(

like image 164
kain64b Avatar answered Sep 29 '22 20:09

kain64b