Remote endpoint display format?

198 views
Skip to first unread message

Robin Kennedy-Reid

unread,
Sep 11, 2019, 7:08:21 AM9/11/19
to WebSocket++
I am using the socket_con_type::get_remote_endpoint function (Line 284 in https://github.com/zaphoyd/websocketpp/blob/master/websocketpp/transport/asio/connection.hpp) in my code.

The function returns a string of format "[::ffff:127.0.0.1]:20662".

Could anyone explain this format to me? I cannot find any in the documentation.

I was expecting I could use this function to return an external IP (in ipv4 format) address for a handler on the other side of the websocket.

Cheers

Peter Thorson

unread,
Sep 11, 2019, 2:49:10 PM9/11/19
to Robin Kennedy-Reid, WebSocket++
Hi Robin,

The string format is passed through from what ASIO returns in the following member function: http://think-async.com/Asio/asio-1.12.2/doc/asio/reference/ip__address/to_string.html

The format is typically an IPv6 address with port where any IPv4 connections use the IPv4 mapped IPv6 format, see https://tools.ietf.org/html/rfc4291#section-2.5.5.2 for more details. This is the format you are seeing.

The reason this is typically done is that because the entire IPv4 space fits in the IPv6 space, this format can be uniform, allowing connections from both address families to be handled using the same logic.

If you explicitly want an IPv4 string there are a few options:

You can use socket_con_type::get_socket() to return the underlying asio::ip::tcp::socket and then use the standard Asio functions to inspect the address of the remote endpoint. Something like..

// lowest layer ensures that you strip out any intermediate socket layers, such as an SSL/TLS wrapper
auto addr = con.get_socket().lowest_layer().remote_endpoint().address();

// check if this is a v4 address
if (addr.is_v4()) {
// cast to a v4 specific address before converting to string
std::string str = addr.to_v4().to_string();
} else {
// v6 address can't be represented as a v4
}

I haven't tested it, but its possible that if you ask the endpoint to listen exclusively on the IPv4 address family that it would print IPv4 address strings by default. Doing this will obviously prevent your application from working on IPv6 networks.

You can ask your endpoint to listen on a specific address family via something like..

endpoint.listen(websocketpp::lib::asio::ip::tcp::v4(), 3000);

--
You received this message because you are subscribed to the Google Groups "WebSocket++" group.
To unsubscribe from this group and stop receiving emails from it, send an email to websocketpp...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/websocketpp/45ae83bc-ca9a-4bc2-91c6-dec73bcd9571%40googlegroups.com.

Peter Thorson

unread,
Sep 12, 2019, 1:42:48 PM9/12/19
to Robin Kennedy-Reid, WebSocket++
Hi Robin,

Hmm, that is not what I would have expected. That might be a question for the Asio documentation or an Asio specific mailing list. Based on some of the options I see here:


There is an is_v4_mapped() method that could check whether an IPv6 address encodes a v4 mapped one and a make_address_v4 function to convert a mapped v6 address to a v4 one that might be worth looking at.

Best,

Peter

On 2019-09-12, at 09:22, Robin Kennedy-Reid <robin.ke...@4sightimaging.com> wrote:

Hi Peter,

Thanks a lot for your response. Your suggestion works well to parse out the port information etc. so I can produce an address in the format "::ffff:127.0.0.1"! Thanks for the documentation on the format too.

My only problem now is that this ipv4-mapped ipv6 address is still stored in an ipv6 type. Thus addr.is_v4() returns false.

Are there any functions that can recognise an ipv4-mapped ipv6 address automatically, and parse accordingly?

Thanks,
Robin

Reply all
Reply to author
Forward
0 new messages