Discussion:
Cygwin socket internals and WinAPI interface
Lukas Haase
2014-05-10 02:50:56 UTC
Permalink
Hi,
From my application I would like to create ("export") a socket in native Windows API which can then be used by cygwin programs.
I.e., if I would write the "server" in cygwin, I would use socket(PF_LOCAL), select, read, write etc. However, I cannot use cygwin because the application is developed in VC and C++ so I want to emulate this functionality using only WinAPI functions.

Socket files are just plain files containing stuff like:

!<socket >54359 s 7B499653-622A1EB9-83E6B83E-A4E8D0C1

The first number is a port number as I understand, the 's' stands for socket I guess but what is the GUID number for?
What steps do I need to perform except creating a windows socket on localhost at this port and writing the socket file?

Thanks
Luke
Corinna Vinschen
2014-05-10 11:51:39 UTC
Permalink
Post by Lukas Haase
Hi,
From my application I would like to create ("export") a socket in
native Windows API which can then be used by cygwin programs.
I.e., if I would write the "server" in cygwin,
Obligatory licensing hint: If you distribute your server outside your
home or company, you're bound by the GPLv3 in terms of source code
distribution.
Post by Lukas Haase
I would use
socket(PF_LOCAL), select, read, write etc. However, I cannot use
cygwin because the application is developed in VC and C++ so I want to
emulate this functionality using only WinAPI functions.
!<socket >54359 s 7B499653-622A1EB9-83E6B83E-A4E8D0C1
The first number is a port number as I understand, the 's' stands for
socket I guess
No. 's' means SOCK_STREAM, 'd' means SOCK_DGRAM.
Post by Lukas Haase
but what is the GUID number for?
It's no GUID but just an array of 4 32 bit values, the AF_LOCAL
"secret". Given that AF_LOCAL sockets are implemented using AF_INET
sockets, there's a chance that a non-aware applicaton tries to connect
to an AF_LOCAL socket. Therefore, the creator of the socket creates a
"secret" and stores it in the socket file. When a AF_LOCAL-aware Cygwin
application connects to this AF_LOCAL socket, it opens the file and
reads the "secret". It can only do so if it has permissions to read the
file. That's all there is for SOCK_DGRAM sockets.

For SOCK_STREAM sockets, the connect/accept attempt starts with
exchanging "secret" and credential packets between client and server.

- Client sends the 16 byte "secret" to the server.
- Server recvs the 16 byte "secret" and compares with its own "secret".
- Server sends own 16 byte "secret".
- Client recvs and compares with its own "secret".

If any of the above fails, the peers close their side of the socket and
return with errno set to ECONNABORTED (accept) or ECONNREFUSED
(connect).

The secret exchange makes sure that the peers both are on the same side.
They know of AF_LOCAL sockets, they have the permissions to open the
socket, and the client and the server are actually using the *same*
AF_LOCAL socket.

If the secret exchange succeeded, two more packets are exchanged:

- Client sends packet with credential data.
- Server answers with credential packet.

A credential packet looks like this:

struct ucred {
pid_t pid;
uid_t uid;
gid_t gid;
};

These are Cygwin pid, uid, and gid, of course. The data is used to
implement getpeereid() and getsockopt(s, SOL_SOCKET, SO_PEERCRED, ...).


HTH,
Corinna
--
Corinna Vinschen Please, send mails regarding Cygwin to
Cygwin Maintainer cygwin AT cygwin DOT com
Red Hat
Loading...