Search code examples
c++unixnetwork-programmingtcpsocat

SOCAT, forwarding TCP socket to a Unix Socket, changes recvmsg() to read(), drops ancillary data


I am using socat to forward a TCP socket to a unix domain socket

Here is an example command:

socat TCP-LISTEN:<PORT> UNIX-CONNECT:<UNIX DOMAIN SOCKET>

I need to read ancillary data out of the socket, and my problem is that socat is 'changing' the recvmsg() calls (from my TCP socket), and normal read() calls on the unix socket. As I understand, there is no way a read() call can get the ancillary data.

My (python) client is remote, and calls recvmsg on the tcp socket.

From a strace of my client:

recvmsg(3, {msg_name(0)=0x7ffc14322490, msg_iov(1)=[{"\360", 1}], msg_controllen=0, msg_flags=0}, 0) = 1
recvmsg(3, {msg_name(0)=0x7ffc14322490, msg_iov(1)=[{"\252", 1}], msg_controllen=0, msg_flags=0}, 0) = 1

Here is a strace of a program that reads directly from the unix socket, The data I need is the [5], in the ancillary data. This is what I want the strace on my remote machine to look like:

recvmmsg(3, {{
{msg_name(0)=NULL, msg_iov(1)=[{"\360", 1}], msg_controllen=20, [{cmsg_len=20, cmsg_level=SOL_SOCKET, cmsg_type=SCM_RIGHTS, [5]}], msg_flags=0}, 1}, {
{msg_name(0)=NULL, msg_iov(1)=[{"\252", 1}], msg_controllen=20, [{cmsg_len=20, cmsg_level=SOL_SOCKET, cmsg_type=SCM_RIGHTS, [6]}], msg_flags=0}, 1}, {

Here is a strace on the remote maching where socat is running / the read syscalls are being made. Notice that its reading the msg_iov data (the non ancillary data). The very top recvmsg's from my client are being translated into read() calls by socat on my remote machine

read(5, "\360", 8192)                   = 1
read(5, "\252", 8192)                   = 1

Is there a way I can make socat not change these recvmsg calls into read() calls?


Solution

  • Ancillary data is not sent over the wire / via TCP. Thats the answer I believe, frustratingly this information is seldom provided.