4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-02-28 03:27:46 +08:00

Cygwin: AF_UNIX: prepare for use of message queues

We will switch to using POSIX message queues instead of Windows pipes
for data transport.  In preparation for that, update the commentary in
fhandler_socket_unix.cc.

Also move the definition of class af_unix_pkt_hdr_t to fhandler.h and
make a few minor changes.
This commit is contained in:
Ken Brown 2021-05-05 14:45:13 -04:00
parent 19a7e4723c
commit 90f4337ea1
2 changed files with 52 additions and 43 deletions

View File

@ -909,6 +909,8 @@ public:
}
};
#ifdef __WITH_AF_UNIX
/* Internal representation of shutdown states */
enum shut_state {
_SHUT_NONE = 0,
@ -1007,7 +1009,31 @@ class af_unix_shmem_t
struct ucred *peer_cred () { return &_peer_cred; }
};
#ifdef __WITH_AF_UNIX
/* See the commentary in fhandler_socket_unix.cc. */
class af_unix_pkt_hdr_t
{
public:
uint16_t pckt_len; /* size of packet including header */
bool admin_pkt : 1; /* admin packets are marked as such */
shut_state shut_info : 2; /* _SHUT_RECV /_SHUT_SEND. */
uint8_t name_len; /* size of name, a sockaddr_un */
uint16_t cmsg_len; /* size of ancillary data block */
uint16_t data_len; /* size of user data */
af_unix_pkt_hdr_t (bool a, shut_state s, uint8_t n, uint16_t c, uint16_t d)
{ init (a, s, n, c, d); }
void init (bool a, shut_state s, uint8_t n, uint16_t c, uint16_t d)
{
admin_pkt = a;
shut_info = s;
name_len = n;
cmsg_len = c;
data_len = d;
pckt_len = sizeof (*this) + name_len + cmsg_len + data_len;
}
};
#define MAX_AF_UN_PKT_LEN UINT16_MAX
class fhandler_socket_unix : public fhandler_socket
{
@ -1064,7 +1090,7 @@ class fhandler_socket_unix : public fhandler_socket
wchar_t get_type_char ();
void set_pipe_non_blocking (bool nonblocking);
int send_sock_info (bool from_bind);
int grab_admin_pkg ();
int grab_admin_pkt ();
int recv_peer_info ();
static NTSTATUS npfs_handle (HANDLE &nph);
HANDLE create_pipe (bool single_instance);

View File

@ -27,6 +27,7 @@ GUID __cygwin_socket_guid = {
#include <sys/param.h>
#include <sys/statvfs.h>
#include <cygwin/acl.h>
#include <mqueue.h>
#include "cygerrno.h"
#include "path.h"
#include "fhandler.h"
@ -38,6 +39,14 @@ GUID __cygwin_socket_guid = {
#include "tls_pbuf.h"
/*
Message queue:
A socket that wants to read creates a POSIX message queue. The
name of the mqueue is "/af-unix-[sd]-<uniq_id>".
- [sd] is s for SOCK_STREAM, d for SOCK_DGRAM
- <uniq_id> is an 8 byte hex unique number
Abstract socket:
An abstract socket is represented by a symlink in the native
@ -50,24 +59,16 @@ GUID __cygwin_socket_guid = {
<sun_path> is the transposed sun_path string, including the leading
NUL. The transposition is simplified in that it uses every byte
in the valid sun_path name as is, no extra multibyte conversion.
The content of the symlink is the basename of the underlying pipe.
The content of the symlink is the name of the underlying mqueue.
Named socket:
A named socket is represented by a reparse point with a Cygwin-specific
tag and GUID. The GenericReparseBuffer content is the basename of the
underlying pipe.
Pipe:
The pipe is named \\.\pipe\cygwin-<installation_key>-unix-[sd]-<uniq_id>
- <installation_key> is the 8 byte hex Cygwin installation key
- [sd] is s for SOCK_STREAM, d for SOCK_DGRAM
- <uniq_id> is an 8 byte hex unique number
tag and GUID. The GenericReparseBuffer content is the name of the
underlying mqueue.
Note: We use MAX_PATH below for convenience where sufficient. It's
big enough to hold sun_paths as well as pipe names as well as packet
big enough to hold sun_paths as well as mqueue names as well as packet
headers etc., so we don't have to use tmp_pathbuf as often.
Every packet sent to a peer is a combination of the socket name of the
@ -76,37 +77,13 @@ GUID __cygwin_socket_guid = {
for the entire packet, as well as for all three data blocks. The
combined maximum size of a packet is 64K, including the header.
A connecting, bound STREAM socket sends it's local sun_path once after
A connecting, bound STREAM socket sends its local sun_path once after
a successful connect. An already connected socket also sends its local
sun_path after a successful bind (border case, but still...). These
packages don't contain any other data (cmsg_len == 0, data_len == 0).
packets don't contain any other data (cmsg_len == 0, data_len == 0).
A bound DGRAM socket sends its sun_path with each sendmsg/sendto.
*/
class af_unix_pkt_hdr_t
{
public:
uint16_t pckt_len; /* size of packet including header */
bool admin_pkg : 1; /* admin packets are marked as such */
shut_state shut_info : 2; /* _SHUT_RECV /_SHUT_SEND. */
uint8_t name_len; /* size of name, a sockaddr_un */
uint16_t cmsg_len; /* size of ancillary data block */
uint16_t data_len; /* size of user data */
af_unix_pkt_hdr_t (bool a, shut_state s, uint8_t n, uint16_t c, uint16_t d)
{ init (a, s, n, c, d); }
void init (bool a, shut_state s, uint8_t n, uint16_t c, uint16_t d)
{
admin_pkg = a;
shut_info = s;
name_len = n;
cmsg_len = c;
data_len = d;
pckt_len = sizeof (*this) + name_len + cmsg_len + data_len;
}
};
#define MAX_AF_UN_PKT_LEN UINT16_MAX
static inline ptrdiff_t
AF_UNIX_PKT_OFFSETOF_NAME (af_unix_pkt_hdr_t *phdr)
@ -276,7 +253,13 @@ fhandler_socket_unix::reopen_shmem ()
#define CYGWIN_PIPE_SOCKET_NAME_LEN 47
/* Character position encoding the socket type in a pipe name. */
#define CYGWIN_PIPE_SOCKET_TYPE_POS 29
#define CYGWIN_PIPE_SOCKET_TYPE_POS 29
/* Character length of mqueue name, excluding trailing NUL. */
#define CYGWIN_MQUEUE_SOCKET_NAME_LEN 27
/* Character position encoding the socket type in an mqueue name. */
#define CYGWIN_MQUEUE_SOCKET_TYPE_POS 9
void
fhandler_socket_unix::gen_pipe_name ()
@ -709,7 +692,7 @@ fhandler_socket_unix::send_sock_info (bool from_bind)
/* Checks if the next packet in the pipe is an administrative packet.
If so, it reads it from the pipe, handles it. Returns an error code. */
int
fhandler_socket_unix::grab_admin_pkg ()
fhandler_socket_unix::grab_admin_pkt ()
{
HANDLE evt;
NTSTATUS status;
@ -727,7 +710,7 @@ fhandler_socket_unix::grab_admin_pkg ()
return 0;
}
af_unix_pkt_hdr_t *packet = (af_unix_pkt_hdr_t *) pbuf->Data;
if (!packet->admin_pkg)
if (!packet->admin_pkt)
io_unlock ();
else
{