10

Recently I found in QNX documentation that it allows to set up message based IPC between processes on separate physical machines by using serial device (dev/serX) and it made me wonder:

Is it possible in Linux to create system-wide special device for TCP/UDP tunnel? Something like nc stdin/stdout exposed publicly under /dev/something.

In the end I'd like to be able to write something to such file on one machine and receive it on the other end for example:

#machine1:
echo "Hello" > /dev/somedev

#machine2:
cat < /dev/somedev

I took a look at nc man but I didn't find any option to specify io source/destination other than stdio.

19

socat can do do this and many other things with things resembling "streams"

Something using this basic idea should do it for you:

Machine1$ socat tcp-l:54321,reuseaddr,fork pty,link=/tmp/netchardev,waitslave

Machine2$ socat pty,link=/tmp/netchardev,waitslave tcp:machine1:54321

(adapted from Examples Page)

If you want to encrypt, you could use a variation of ssl-l:54321,reuseaddr,cert=server.pem,cafile=client.crt,fork on machine1, and something like ssl:server-host:1443,cert=client.pem,cafile=server.crt on machine2

(More about socat ssl)

7

Message-passing needs to be implemented at a higher layer; TCP does not have a notion of a message -- the TCP connections transfer streams of octets.

You can achieve something sort-of like what you request with nc and named pipes, see man mkfifo; or check socat as Alex Stragies indicates.

Without a middle-layer service, the basic problems are (1) that data cannot be written to the network unless there is somebody at the other end listening for it, and (2) that TCP connections are bi-directional.

Because you cannot write data to the network unless somebody is listening for it, you must always start the listener before you can send data. (In a message passing system the process handling the messages will provide some sort of buffering.)

Your example can be easily rewritten:

  • First start a listener on machine2 (the destination):

     nc -l 1234 | ...some processing with the received data...
    

    In your example, this would be

     nc -l 1234 | cat
    

    This will block and wait for somebody to send some data to port 1234.

  • Then you can send some data from machine1 (the source):

    ...make up some data... | nc machine2 1234
    

    In your example, this would be

     echo "Hello" | nc machine2 1234
    

If you want to process the received data in some way and respond you can use the coprocessing facility of the shell. For example, this is a very simple (and very stubborn) web server:

#! /bin/bash

while :; do
  coproc ncfd { nc -l 1234; }
  while :; do
    read line <&${ncfd[0]} || break
    line="$(
      echo "$line" |
      LC_ALL=C tr -cd ' -~'
    )"
    echo >&2 "Received: \"$line\""
    if [ "$line" = "" ]; then
      echo >&${ncfd[1]} "HTTP/1.0 200 OK"
      echo >&${ncfd[1]} "Content-Type: text/html"
      echo >&${ncfd[1]} "Connection: close"
      echo >&${ncfd[1]} ""
      echo >&${ncfd[1]} "<title>It works!</title>"
      echo >&${ncfd[1]} "<center><b>It works!</b></center>"
      echo >&${ncfd[1]} "<center>-- $(date +%Y-%m-%d\ %H:%M:%S) --</center>"
      break
    fi
  done
  kill %%
  sleep 0.1
done

See how the bi-directional communication is achieved between the main body of the script and the coprocess using the file descriptors in the array $ncfd.

  • You are right, and I have acknowledged that in the answer. Cannot have a character device without some sort of mediating software. – AlexP Dec 5 '16 at 1:03
  • Looks like you have a UUOC there. – Michael Hampton Dec 5 '16 at 20:36
  • 1
    @MichaelHampton: That was the example provided by the OP. I suppose that cat stands for "some process reading for stdin". – AlexP Dec 5 '16 at 21:07
5

If you simply want to connect two computers using a basic program like nc you can redirect from/to /dev/tcp/<host>/<port>.

These are not actual devices but a fiction created by bash, so things like cat /dev/tcp/foo/19 won't work, but cat < /dev/tcp/foo/19 will.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.