Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions include/msocket.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,12 @@ typedef struct msocket_addr_info_tag {

typedef msocket_addr_info_t msocketAddrInfo_t;

typedef struct msocket_credentials_tag {
int pid;
int uid;
int gid;
} msocket_credentials_t;

typedef struct msocket_tag {
msocket_addr_info_t stream_info;
msocket_addr_info_t udp_info;
Expand Down Expand Up @@ -230,6 +236,15 @@ msocket_error_t msocket_listen(msocket_t *self, uint8_t mode, uint16_t port, con
*/
msocket_error_t msocket_unix_listen(msocket_t *self, const char *socket_path);

/**
* Adopts an already-bound and listening UNIX domain socket file descriptor (POSIX only).
*
* @param self Pointer to msocket_t instance.
* @param fd Pre-bound listening file descriptor (e.g. from systemd socket activation).
* @return MSOCKET_NO_ERROR on success, or error code on failure.
*/
msocket_error_t msocket_unix_listen_fd(msocket_t *self, int fd);

/**
* Binds and configures a listening VSOCK socket (Linux only).
*
Expand Down Expand Up @@ -311,6 +326,17 @@ msocket_error_t msocket_connect(msocket_t *self, const char *addr, uint16_t port
*/
msocket_error_t msocket_unix_connect(msocket_t *self, const char *socket_path);

/**
* Retrieves the OS peer credentials (PID, UID, GID) for a connected UNIX socket.
*
* @param self Pointer to connected msocket_t instance.
* @param credentials Output pointer to receive the peer credentials.
* @return MSOCKET_NO_ERROR on success, MSOCKET_INVALID_ARGUMENT_ERROR on invalid parameters,
* MSOCKET_NOT_IMPLEMENTED_ERROR on unsupported platforms/socket types,
* or MSOCKET_SOCKET_ERROR on failure.
*/
msocket_error_t msocket_get_peer_credentials(const msocket_t *self, msocket_credentials_t *credentials);

/**
* Initiates an outgoing VSOCK connection (Linux only).
*
Expand Down
9 changes: 9 additions & 0 deletions include/msocket_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ typedef struct msocket_server_tag {
uint16_t udp_port;
char *udp_addr;
char *socket_path;
int unix_fd;
uint32_t vsock_cid;
uint32_t vsock_port;
adt_ary_t cleanup_items;
Expand Down Expand Up @@ -126,6 +127,14 @@ void msocket_server_start(msocket_server_t *self, const char *udp_addr, uint16_t
*/
void msocket_server_unix_start(msocket_server_t *self, const char *socket_path);

/**
* Starts the server using an already-bound and listening UNIX domain socket file descriptor (POSIX only).
*
* @param self Pointer to msocket_server_t instance.
* @param fd Pre-bound listening file descriptor (e.g. from systemd socket activation).
*/
void msocket_server_unix_start_fd(msocket_server_t *self, int fd);

/**
* Binds a listening VSOCK socket and starts the server threads (Linux only).
*
Expand Down
19 changes: 19 additions & 0 deletions source/msocket_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,14 @@ msocket_error_t msocket_unix_listen(msocket_t *self, const char *socket_path)
return msocket_os_unix_listen(self, socket_path);
}

msocket_error_t msocket_unix_listen_fd(msocket_t *self, int fd)
{
if (self == NULL || fd < 0) {
return MSOCKET_INVALID_ARGUMENT_ERROR;
}
return msocket_os_unix_listen_fd(self, fd);
}

msocket_error_t msocket_vsock_listen(msocket_t *self, uint32_t cid, uint32_t port)
{
if (self == NULL || self->address_family != MSOCKET_ADDR_VSOCK || port == 0u) {
Expand Down Expand Up @@ -620,6 +628,17 @@ msocket_error_t msocket_unix_connect(msocket_t *self, const char *socket_path)
return msocket_os_unix_connect(self, socket_path);
}

msocket_error_t msocket_get_peer_credentials(const msocket_t *self, msocket_credentials_t *credentials)
{
if (self == NULL || credentials == NULL) {
return MSOCKET_INVALID_ARGUMENT_ERROR;
}
if (self->address_family != MSOCKET_ADDR_UNIX) {
return MSOCKET_NOT_IMPLEMENTED_ERROR;
}
return msocket_os_get_peer_credentials(self, credentials);
}

msocket_error_t msocket_vsock_connect(msocket_t *self, uint32_t cid, uint32_t port)
{
if (self == NULL || port == 0u || (self->socket_mode & MSOCKET_MODE_STREAM) != 0) {
Expand Down
2 changes: 2 additions & 0 deletions source/msocket_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,9 @@ void msocket_os_mutex_lock(msocket_os_t *os);
void msocket_os_mutex_unlock(msocket_os_t *os);

msocket_error_t msocket_os_unix_listen(msocket_t *self, const char *socket_path);
msocket_error_t msocket_os_unix_listen_fd(msocket_t *self, int fd);
msocket_error_t msocket_os_unix_connect(msocket_t *self, const char *socket_path);
msocket_error_t msocket_os_get_peer_credentials(const msocket_t *self, msocket_credentials_t *credentials);

msocket_error_t msocket_os_vsock_listen(msocket_t *self, uint32_t cid, uint32_t port);
msocket_error_t msocket_os_vsock_connect(msocket_t *self, uint32_t cid, uint32_t port);
Expand Down
37 changes: 37 additions & 0 deletions source/msocket_posix.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
* See LICENSE in project root for full license terms.
******************************************************************************/

#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif

//////////////////////////////////////////////////////////////////////////////
// INCLUDES
//////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -184,6 +188,17 @@ msocket_error_t msocket_os_unix_listen(msocket_t *self, const char *socket_path)
return MSOCKET_NO_ERROR;
}

msocket_error_t msocket_os_unix_listen_fd(msocket_t *self, int fd)
{
if (fd < 0) {
return MSOCKET_INVALID_ARGUMENT_ERROR;
}
self->os->tcp_sockfd = fd;
self->state = MSOCKET_STATE_LISTENING;
self->socket_mode |= MSOCKET_MODE_STREAM;
return MSOCKET_NO_ERROR;
}

msocket_error_t msocket_os_unix_connect(msocket_t *self, const char *socket_path)
{
struct sockaddr_un saddr;
Expand Down Expand Up @@ -224,6 +239,28 @@ msocket_error_t msocket_os_unix_connect(msocket_t *self, const char *socket_path
return MSOCKET_NO_ERROR;
}

msocket_error_t msocket_os_get_peer_credentials(const msocket_t *self, msocket_credentials_t *credentials)
{
#if defined(SO_PEERCRED)
struct ucred ucred;
socklen_t len = (socklen_t)sizeof(struct ucred);
if (self->os == NULL || OS_SOCKET_IS_INVALID(self->os->tcp_sockfd)) {
return MSOCKET_SOCKET_ERROR;
}
if (getsockopt(self->os->tcp_sockfd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) < 0) {
return MSOCKET_SOCKET_ERROR;
}
credentials->pid = (int)ucred.pid;
credentials->uid = (int)ucred.uid;
credentials->gid = (int)ucred.gid;
return MSOCKET_NO_ERROR;
#else
(void)self;
(void)credentials;
return MSOCKET_NOT_IMPLEMENTED_ERROR;
#endif
}

//////////////////////////////////////////////////////////////////////////////
// VSOCK SOCKETS
//////////////////////////////////////////////////////////////////////////////
Expand Down
25 changes: 25 additions & 0 deletions source/msocket_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ void msocket_server_create(msocket_server_t *self, uint8_t address_family, void
self->udp_port = 0u;
self->udp_addr = NULL;
self->socket_path = NULL;
self->unix_fd = -1;
self->vsock_cid = 0u;
self->vsock_port = 0u;
self->accept_socket = NULL;
Expand Down Expand Up @@ -104,6 +105,7 @@ void msocket_server_destroy(msocket_server_t *self)
free(self->socket_path);
self->socket_path = NULL;
}
self->unix_fd = -1;

#if defined(MSOCKET_ENABLE_TLS)
if (self->tls_server != NULL) {
Expand Down Expand Up @@ -146,6 +148,7 @@ void msocket_server_start(msocket_server_t *self, const char *udp_addr, uint16_t
if (self != NULL) {
self->tcp_port = tcp_port;
self->udp_port = udp_port;
self->unix_fd = -1;
if (udp_addr != NULL) {
size_t len = strlen(udp_addr) + 1u;
self->udp_addr = (char *)malloc(len);
Expand All @@ -162,6 +165,7 @@ void msocket_server_unix_start(msocket_server_t *self, const char *socket_path)
if (self != NULL && socket_path != NULL) {
self->tcp_port = 0u;
self->udp_port = 0u;
self->unix_fd = -1;
size_t len = (*socket_path == '\0') ? (strlen(socket_path + 1) + 2u) : (strlen(socket_path) + 1u);
self->socket_path = (char *)malloc(len);
if (self->socket_path != NULL) {
Expand All @@ -171,11 +175,22 @@ void msocket_server_unix_start(msocket_server_t *self, const char *socket_path)
}
}

void msocket_server_unix_start_fd(msocket_server_t *self, int fd)
{
if (self != NULL && fd >= 0) {
self->tcp_port = 0u;
self->udp_port = 0u;
self->unix_fd = fd;
msocket_server_start_threads(self);
}
}

void msocket_server_vsock_start(msocket_server_t *self, uint32_t cid, uint32_t port)
{
if (self != NULL && port != 0u) {
self->tcp_port = 0u;
self->udp_port = 0u;
self->unix_fd = -1;
self->vsock_cid = cid;
self->vsock_port = port;
msocket_server_start_threads(self);
Expand Down Expand Up @@ -271,6 +286,16 @@ static msocket_error_t msocket_server_bind(msocket_server_t *self)
}
}

if (self->unix_fd >= 0) {
rc = msocket_unix_listen_fd(self->accept_socket, self->unix_fd);
if (rc != MSOCKET_NO_ERROR) {
fprintf(stderr, "[MSOCKET_SERVER] Failed to adopt UNIX fd %d\n", self->unix_fd);
msocket_delete(self->accept_socket);
self->accept_socket = NULL;
return rc;
}
}

if (self->vsock_port != 0u) {
rc = msocket_vsock_listen(self->accept_socket, self->vsock_cid, self->vsock_port);
if (rc != MSOCKET_NO_ERROR) {
Expand Down
14 changes: 14 additions & 0 deletions source/msocket_windows.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,13 +164,27 @@ msocket_error_t msocket_os_unix_listen(msocket_t *self, const char *socket_path)
return MSOCKET_NOT_IMPLEMENTED_ERROR;
}

msocket_error_t msocket_os_unix_listen_fd(msocket_t *self, int fd)
{
(void)self;
(void)fd;
return MSOCKET_NOT_IMPLEMENTED_ERROR;
}

msocket_error_t msocket_os_unix_connect(msocket_t *self, const char *socket_path)
{
(void)self;
(void)socket_path;
return MSOCKET_NOT_IMPLEMENTED_ERROR;
}

msocket_error_t msocket_os_get_peer_credentials(const msocket_t *self, msocket_credentials_t *credentials)
{
(void)self;
(void)credentials;
return MSOCKET_NOT_IMPLEMENTED_ERROR;
}

//////////////////////////////////////////////////////////////////////////////
// VSOCK (WINDOWS STUBS)
//////////////////////////////////////////////////////////////////////////////
Expand Down
Loading
Loading