0

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?

e wagness
  • 301
  • 2
  • 13
  • 1
    What comes out of your Unix socket `recvmsg()` calls? Because TCP is just a stream and all the information from `sendmsg()` is gathered into a single packet and sent over the connection. See [this question](https://stackoverflow.com/questions/4258834/how-sendmsg-works) and in particular [this answer](https://stackoverflow.com/a/4259888/4756299): "For a stream socket, it wouldn't matter either way. Any data you send will just end up as one long stream of data on the other side." – Andrew Henle May 29 '19 at 17:01
  • @AndrewHenle I'm not sure what you mean, my problem is that recvmsg is NOT being called on the unix socket. The example I have above of the recvmsg on the unix socket is from a separate program I wrote which reads the unix socket directly. What comes out is the [5], its an int / file descriptor. read is being called on the unix socket instead though (when using socat), which as I understand ignores ancillary data – e wagness May 29 '19 at 18:07
  • 1
    Are you trying to pass an integer value file descriptor over a TCP socket, through `socat`, and the out the Unix socket? Or the opposite way - through a Unix socket, then through `socat` and then over a TCP connection to a remote machine? – Andrew Henle May 29 '19 at 18:33
  • @AndrewHenle I think my problem may be with python, and I've opened a separate question. I am trying to read from a unix socket, which replies to the read with an integer FD. My client is remote (its a functional test) so it cant run locally on the target machine w/ the Unix socket. So instead, I am trying to use socat to forward a TCP socket to a Unix socket, so my client can 'use' a TCP socket to read / recv on the unix socket with socat as a proxy of sorts. – e wagness May 29 '19 at 18:40

1 Answers1

0

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

e wagness
  • 301
  • 2
  • 13