views:

724

answers:

3

I'm curious if it is possible to map a UNIX socket on to an INET socket. The situation is simply that I'd like to connect to a MySQL server. Unfortunately it has INET sockets disabled and therefore I can only connect with UNIX sockets. The tools I'm using/writing have to connect on an INET socket, so I'm trying to see if I can map one on to the other.

It took a fair amount of searching but I did find socat, which purportedly does what I'm looking for. I was wondering if anyone has any suggestions on how to accomplish this. The command-line I've been using (with partial success) is:

socat -v UNIX-CONNECT:/var/lib/mysql/mysql.sock TCP-LISTEN:6666,reuseaddr

Now I can make connections and talk to the server. Unfortunately any attempts at making multiple connections fail as I need to use the fork option but this option seems to render the connections nonfunctional.

I know I can tackle the issue with Perl (my preferred language), but I'd rather avoid writing the entire implementation myself. I familiar with the IO::Socket libraries, I am simply hoping anyone has experience doing this sort of thing. Open to suggestions/ideas.

Thanks.

A: 

Yes, you can do this in Perl.

Look at perlipc, IO::Select, IO::Socket and Beej's Guide to Network Programming.

daotoad
A: 

You might want to consider doing it in POE - it's asynchronous library for dealing with events, so it looks like great for the task.

It is not 100% relevant, but I use POE to write proxy between stateless protocol (HTTP) and statefull protocol (telnet session, and more specifically - MUD session), and it was rather simple - You can check the code in here: http://www.depesz.com/index.php/2009/04/08/learning-poe-http-2-mud-proxy/.

In the comments somebody also suggested Coro/AnyEvent - I haven't played with it yet, but you might want to check it.

depesz
+3  A: 

Reverse the order of your arguments to socat, and it works.

socat -v tcp-l:6666,reuseaddr,fork unix:/var/lib/mysql/mysql.sock

This instructs socat to

  1. Listen on TCP port 6666 (with SO_REUSEADDR)
  2. Wait to accept a connection
  3. When a connection is made, fork. In the child, continue the steps below. In the parent, go to 2.
  4. Open a UNIX domain connection to the /var/lib/mysql/mysql.sock socket.
  5. Transfer data between the two endpoints, then exit.


Writing it the other way around

socat -v unix:/var/lib/mysql/mysql.sock tcp-l:6666,reuseaddr,fork

doesn't work, because this instructs socat to

  1. Open a UNIX domain connection to the /var/lib/mysql/mysql.sock socket.
  2. Listen on TCP port 6666 (with SO_REUSEADDR)
  3. Wait to accept a connection
  4. When a connection is made, spawn a worker child to transfer data between the two addresses.
  5. The parent continues to accept connections on the second address, but no longer has the first address available: it was given to the first child. So nothing useful can be done from this point on.
ephemient
Thank you, that is exactly what I was looking for. Amazing, what a silly mistake it was.
Danny