How can I “interconnect” two sockets in Linux?

2019-02-09 05:32发布

There are two connected sockets. How can I interconnect them?

  1. Data appeared on the one socket should be written to the other.
  2. EOF/FIN should propogate well. If one is half-closed, the other should also be half-closed.
int client = get_connected_client_socket();
int proxy = get_connected_proxy_socket();
negotiate_with_proxy(proxy);
iterconnect(client, proxy); 
// Now forgot about both client and proxy. 
// System should handle IO/shutdown/close. 
// Ideally even without any support of the user-space process.

Can Linux do it? Can it be done by tricking connection tracking to change tracking status of existing connection?

@related Determine how much can I write into a filehandle; copying data from one FH to the other

4条回答
beautiful°
2楼-- · 2019-02-09 06:07

You will need a userspace process to hang around and do the copying of data from one socket to the other. It's pretty simple though:

  • Any data read from socket A, write to socket B;
  • Any data read from socket B, write to socket A;
  • If read returns 0 on socket A, call shutdown(SHUT_WR) on socket B;
  • If read returns 0 on socket B, call shutdown(SHUT_WR) on socket A;
  • Once both sockets have returned 0 from read, close both sockets and exit;
  • If either socket returns EPIPE, close both sockets and exit.

As Newton Falls mentions, you can use splice() to do this in a zero-copy manner, but that's just a performance enhancement; get it working with read/write first. You should be able to just fork() off a child to do this, which will make it "fire and forget" for your main process.

查看更多
ゆ 、 Hurt°
3楼-- · 2019-02-09 06:09

A unix domain socket may help. See the man page:

man unix
查看更多
劫难
4楼-- · 2019-02-09 06:12

Checkout the socat tool. That's the best tool to solve this kind of problems.

查看更多
萌系小妹纸
5楼-- · 2019-02-09 06:19

Are you aware of splice(). Based on your two questions I think this is where you are headed. Last I checked you can't do this in one splice call because both of file descriptors can't be sockets. But you should be able to do it in 2 calls (sockin->pipe->sockout). Also take a look at tee(). These may not be exactly what you want but from what I can figure they are in the ballpark.

查看更多
登录 后发表回答