How to connect to an unix domain socket with boost::asio?
Asked Answered
L

2

8

I want to create and connect to an unix domain socket of type SOCK_SEQPACKET by specifying the path name of the socket endpoint, but this fails to compile in boost::asio v1.60:

using namespace boost::asio::generic;
seq_packet_protocol proto{AF_UNIX, IPPROTO_SCTP}; // SOCK_SEQPACKET
seq_packet_protocol::socket sock(io_service, proto);
boost::asio::local::basic_endpoint<seq_packet_protocol> ep("/tmp/socket");
sock.connect(ep); // does not compile

do you know how to properly create an unix domain socket?

Laplante answered 6/5, 2016 at 20:9 Comment(0)
S
6

I suggest to keep it simple:

#include <boost/asio.hpp>

int main() {
    boost::asio::io_service io_service;
    using boost::asio::local::stream_protocol;

    stream_protocol::socket s(io_service);
    s.connect("/tmp/socket");
}

No doubt you can go more lowlevel, but I'm not sure when you'd need that.

UPDATE 2 In Boost 1.82.0, Asio 1.27.0 added local::seq_packet_protocol

UPDATE Mimicking the pre-defined stream_protocol, here's how to define seqpacket_protocol:

Live On Coliru

namespace SeqPacket {
    using namespace boost::asio::local;

    struct seqpacket_protocol
    {
        int type()     const { return IPPROTO_SCTP; }
        int protocol() const { return 0;            }
        int family()   const { return AF_UNIX;      }

        typedef basic_endpoint<seqpacket_protocol> endpoint;
        typedef boost::asio::basic_stream_socket<seqpacket_protocol> socket;
        typedef boost::asio::basic_socket_acceptor<seqpacket_protocol> acceptor;

#if !defined(BOOST_ASIO_NO_IOSTREAM)
        /// The UNIX domain iostream type.
        typedef boost::asio::basic_socket_iostream<seqpacket_protocol> iostream;
#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
    };
}

Just use it in the same pattern:

int main() {
    boost::asio::io_service io_service;
    using SeqPacket::seqpacket_protocol;

    seqpacket_protocol::socket s(io_service);
    s.connect("socket");
}
Sennet answered 6/5, 2016 at 21:55 Comment(9)
I'll read up a bit to see if I can understand what the SEQPACKET does. I may update if I get it :)Sennet
Updated with a sample that uses IPPROTO_SCTP as prescribed.Sennet
many thanks, but I wonder why the authors did not add seqpacket to the ::local protocol setLaplante
There's always gonna be arbitrary choices and skipped features. What matters is that the things are supported in principle.Sennet
should not protocol() be IPPROTO_SCTP and type() 0 (or SOCK_SEQPACKET) ? Secondly, I wrote a server and a client following the asio examples (under unix domain socket) by replacing stream_protocol with seqpacket_protocol and using various combinations of protocol() and type() until the forementioned one. The server runs fine, but the client fails to connect() throwing: "Exception: connect: Invalid argument". Do you have any idea?Laplante
It seems IPPROTO_SCTP is not supported with unix domain sockets, am I right? so I used used (family=AF_UNIX, protocol=0, type=SOCK_SEQPACKET). The server runs fine -apparently- as I said, but the client thorws the exception mentioned above on connect()Laplante
Sadly my disclaimer still holds: "No doubt you can go more lowlevel, but I'm not sure when you'd need that". I have no idea what you're trying to do and whether it makes sense. I was just helping you with the technicals of the code, as you asked.Sennet
Thanks, this answer helped a lot! BTW @Laplante is right, type should be SOCK_SEQPACKET.Tishtisha
@Laplante they did in 1.82.0, just noticed. You can probably spelunk who contributed it, so as to answer your original question more precisely.Sennet
R
0

To add on to sehe's answer, the socket definition is wrong, it should be:

typedef boost::asio::basic_seq_packet_socket<seqpacket_protocol> socket;

putting it together:

namespace SeqPacket {
    struct seqpacket_protocol
    {
        int type()     const { return SOCK_SEQPACKET; }
        int protocol() const { return 0;            }
        int family()   const { return AF_UNIX;      }

        typedef boost::asio::local::basic_endpoint<seqpacket_protocol> endpoint;
        typedef boost::asio::basic_seq_packet_socket<seqpacket_protocol> socket;
        typedef boost::asio::basic_socket_acceptor<seqpacket_protocol> acceptor;

#if !defined(BOOST_ASIO_NO_IOSTREAM)
        /// The UNIX domain iostream type.
        typedef boost::asio::basic_socket_iostream<seqpacket_protocol> iostream;
#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
    };
}
Rejoinder answered 16/9, 2020 at 5:39 Comment(1)
Fyi, 1.82.0, added local::seq_packet_protocolSennet

© 2022 - 2024 — McMap. All rights reserved.