Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[IP6NS Grant] Make socket family handling portable #1126

Merged
merged 1 commit into from Aug 7, 2019
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
380 changes: 192 additions & 188 deletions lib/MAST/Ops.nqp

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions src/core/interp.c
Expand Up @@ -3641,17 +3641,17 @@ void MVM_interp_run(MVMThreadContext *tc, void (*initial_invoke)(MVMThreadContex
goto NEXT;
OP(connect_sk):
MVM_io_connect(tc, GET_REG(cur_op, 0).o,
GET_REG(cur_op, 2).s, GET_REG(cur_op, 4).i64);
cur_op += 6;
GET_REG(cur_op, 2).s, GET_REG(cur_op, 4).i64, GET_REG(cur_op, 6).u16);
cur_op += 8;
goto NEXT;
OP(socket):
GET_REG(cur_op, 0).o = MVM_io_socket_create(tc, GET_REG(cur_op, 2).i64);
cur_op += 4;
goto NEXT;
OP(bind_sk):
MVM_io_bind(tc, GET_REG(cur_op, 0).o,
GET_REG(cur_op, 2).s, GET_REG(cur_op, 4).i64, (MVMint32)GET_REG(cur_op, 6).i64);
cur_op += 8;
GET_REG(cur_op, 2).s, GET_REG(cur_op, 4).i64, GET_REG(cur_op, 6).u16, (MVMint32)GET_REG(cur_op, 8).i64);
cur_op += 10;
goto NEXT;
OP(accept_sk):
GET_REG(cur_op, 0).o = MVM_io_accept(tc, GET_REG(cur_op, 2).o);
Expand Down
4 changes: 2 additions & 2 deletions src/core/oplist
Expand Up @@ -543,9 +543,9 @@ eof_fh w(int64) r(obj)
getstdin w(obj) :pure
getstdout w(obj) :pure
getstderr w(obj) :pure
connect_sk r(obj) r(str) r(int64)
connect_sk r(obj) r(str) r(int64) r(uint16)
socket w(obj) r(int64)
bind_sk r(obj) r(str) r(int64) r(int64)
bind_sk r(obj) r(str) r(int64) r(uint16) r(int64)
DEPRECATED_24 r(obj) r(str)
accept_sk w(obj) r(obj)
decodetocodes r(obj) r(str) r(int64) r(obj)
Expand Down
8 changes: 4 additions & 4 deletions src/core/ops.c
Expand Up @@ -6804,7 +6804,7 @@ static const MVMOpInfo MVM_op_infos[] = {
{
MVM_OP_connect_sk,
"connect_sk",
3,
4,
0,
0,
0,
Expand All @@ -6813,7 +6813,7 @@ static const MVMOpInfo MVM_op_infos[] = {
0,
0,
0,
{ MVM_operand_read_reg | MVM_operand_obj, MVM_operand_read_reg | MVM_operand_str, MVM_operand_read_reg | MVM_operand_int64 }
{ MVM_operand_read_reg | MVM_operand_obj, MVM_operand_read_reg | MVM_operand_str, MVM_operand_read_reg | MVM_operand_int64, MVM_operand_read_reg | MVM_operand_uint16 }
},
{
MVM_OP_socket,
Expand All @@ -6832,7 +6832,7 @@ static const MVMOpInfo MVM_op_infos[] = {
{
MVM_OP_bind_sk,
"bind_sk",
4,
5,
0,
0,
0,
Expand All @@ -6841,7 +6841,7 @@ static const MVMOpInfo MVM_op_infos[] = {
0,
0,
0,
{ MVM_operand_read_reg | MVM_operand_obj, MVM_operand_read_reg | MVM_operand_str, MVM_operand_read_reg | MVM_operand_int64, MVM_operand_read_reg | MVM_operand_int64 }
{ MVM_operand_read_reg | MVM_operand_obj, MVM_operand_read_reg | MVM_operand_str, MVM_operand_read_reg | MVM_operand_int64, MVM_operand_read_reg | MVM_operand_uint16, MVM_operand_read_reg | MVM_operand_int64 }
},
{
MVM_OP_DEPRECATED_24,
Expand Down
4 changes: 2 additions & 2 deletions src/io/asyncsocket.c
Expand Up @@ -654,7 +654,7 @@ MVMObject * MVM_io_socket_connect_async(MVMThreadContext *tc, MVMObject *queue,

/* Resolve hostname. (Could be done asynchronously too.) */
MVMROOT3(tc, queue, schedulee, async_type, {
dest = MVM_io_resolve_host_name(tc, host, port);
dest = MVM_io_resolve_host_name(tc, host, port, SOCKET_FAMILY_UNSPEC);
});

/* Create async task handle. */
Expand Down Expand Up @@ -873,7 +873,7 @@ MVMObject * MVM_io_socket_listen_async(MVMThreadContext *tc, MVMObject *queue,

/* Resolve hostname. (Could be done asynchronously too.) */
MVMROOT3(tc, queue, schedulee, async_type, {
dest = MVM_io_resolve_host_name(tc, host, port);
dest = MVM_io_resolve_host_name(tc, host, port, SOCKET_FAMILY_UNSPEC);
});

/* Create async task handle. */
Expand Down
4 changes: 2 additions & 2 deletions src/io/asyncsocketudp.c
Expand Up @@ -388,7 +388,7 @@ static MVMAsyncTask * write_bytes_to(MVMThreadContext *tc, MVMOSHandle *h, MVMOb
/* Resolve destination and create async task handle. */
MVMROOT4(tc, queue, schedulee, h, buffer, {
MVMROOT(tc, async_type, {
dest_addr = MVM_io_resolve_host_name(tc, host, port);
dest_addr = MVM_io_resolve_host_name(tc, host, port, SOCKET_FAMILY_UNSPEC);
});
task = (MVMAsyncTask *)MVM_repr_alloc_init(tc, async_type);
});
Expand Down Expand Up @@ -577,7 +577,7 @@ MVMObject * MVM_io_socket_udp_async(MVMThreadContext *tc, MVMObject *queue,
/* Resolve hostname. (Could be done asynchronously too.) */
if (host && IS_CONCRETE(host)) {
MVMROOT3(tc, queue, schedulee, async_type, {
bind_addr = MVM_io_resolve_host_name(tc, host, port);
bind_addr = MVM_io_resolve_host_name(tc, host, port, SOCKET_FAMILY_UNSPEC);
});
}

Expand Down
8 changes: 4 additions & 4 deletions src/io/io.c
Expand Up @@ -304,25 +304,25 @@ void MVM_io_truncate(MVMThreadContext *tc, MVMObject *oshandle, MVMint64 offset)
MVM_exception_throw_adhoc(tc, "Cannot truncate this kind of handle");
}

void MVM_io_connect(MVMThreadContext *tc, MVMObject *oshandle, MVMString *host, MVMint64 port) {
void MVM_io_connect(MVMThreadContext *tc, MVMObject *oshandle, MVMString *host, MVMint64 port, MVMuint16 family) {
MVMOSHandle *handle = verify_is_handle(tc, oshandle, "connect");
if (handle->body.ops->sockety) {
MVMROOT2(tc, host, handle, {
uv_mutex_t *mutex = acquire_mutex(tc, handle);
handle->body.ops->sockety->connect(tc, handle, host, port);
handle->body.ops->sockety->connect(tc, handle, host, port, family);
release_mutex(tc, mutex);
});
}
else
MVM_exception_throw_adhoc(tc, "Cannot connect this kind of handle");
}

void MVM_io_bind(MVMThreadContext *tc, MVMObject *oshandle, MVMString *host, MVMint64 port, MVMint32 backlog) {
void MVM_io_bind(MVMThreadContext *tc, MVMObject *oshandle, MVMString *host, MVMint64 port, MVMuint16 family, MVMint32 backlog) {
MVMOSHandle *handle = verify_is_handle(tc, oshandle, "bind");
if (handle->body.ops->sockety) {
MVMROOT2(tc, host, handle, {
uv_mutex_t *mutex = acquire_mutex(tc, handle);
handle->body.ops->sockety->bind(tc, handle, host, port, backlog);
handle->body.ops->sockety->bind(tc, handle, host, port, family, backlog);
release_mutex(tc, mutex);
});
}
Expand Down
8 changes: 4 additions & 4 deletions src/io/io.h
Expand Up @@ -67,8 +67,8 @@ struct MVMIOSeekable {

/* I/O operations on handles that do socket-y things (connect, bind, accept). */
struct MVMIOSockety {
void (*connect) (MVMThreadContext *tc, MVMOSHandle *h, MVMString *host, MVMint64 port);
void (*bind) (MVMThreadContext *tc, MVMOSHandle *h, MVMString *host, MVMint64 port, MVMint32 backlog);
void (*connect) (MVMThreadContext *tc, MVMOSHandle *h, MVMString *host, MVMint64 port, MVMuint16 family);
void (*bind) (MVMThreadContext *tc, MVMOSHandle *h, MVMString *host, MVMint64 port, MVMuint16 family, MVMint32 backlog);
MVMObject * (*accept) (MVMThreadContext *tc, MVMOSHandle *h);
MVMint64 (*getport) (MVMThreadContext *tc, MVMOSHandle *h);
};
Expand Down Expand Up @@ -105,8 +105,8 @@ MVMint64 MVM_io_lock(MVMThreadContext *tc, MVMObject *oshandle, MVMint64 flag);
void MVM_io_unlock(MVMThreadContext *tc, MVMObject *oshandle);
void MVM_io_flush(MVMThreadContext *tc, MVMObject *oshandle, MVMint32 sync);
void MVM_io_truncate(MVMThreadContext *tc, MVMObject *oshandle, MVMint64 offset);
void MVM_io_connect(MVMThreadContext *tc, MVMObject *oshandle, MVMString *host, MVMint64 port);
void MVM_io_bind(MVMThreadContext *tc, MVMObject *oshandle, MVMString *host, MVMint64 port, MVMint32 backlog);
void MVM_io_connect(MVMThreadContext *tc, MVMObject *oshandle, MVMString *host, MVMint64 port, MVMuint16 family);
void MVM_io_bind(MVMThreadContext *tc, MVMObject *oshandle, MVMString *host, MVMint64 port, MVMuint16 family, MVMint32 backlog);
MVMObject * MVM_io_accept(MVMThreadContext *tc, MVMObject *oshandle);
MVMint64 MVM_io_getport(MVMThreadContext *tc, MVMObject *oshandle);
void MVM_io_set_buffer_size(MVMThreadContext *tc, MVMObject *oshandle, MVMint64 size);
Expand Down
55 changes: 36 additions & 19 deletions src/io/syncsocket.c
Expand Up @@ -256,39 +256,39 @@ static size_t get_struct_size_for_family(sa_family_t family) {
}
}

/* This function may return any type of sockaddr e.g. sockaddr_un, sockaddr_in or sockaddr_in6
/*
* This function may return any type of sockaddr e.g. sockaddr_un, sockaddr_in or sockaddr_in6
* It shouldn't be a problem with general code as long as the port number is kept below the int16 limit: 65536
* After this it defines the family which may spawn non internet sockaddr's
* The family can be extracted by (port >> 16) & USHORT_MAX
*
* Currently supported families:
*
* AF_UNSPEC = 1
* SOCKET_FAMILY_UNSPEC = 0
* Unspecified, in most cases should be equal to AF_INET or AF_INET6
*
* AF_UNIX = 1
* Unix domain socket, will spawn a sockaddr_un which will use the given host as path
* e.g: MVM_io_resolve_host_name(tc, "/run/moarvm.sock", 1 << 16)
* will spawn an unix domain socket on /run/moarvm.sock
*
* AF_INET = 2
* SOCKET_FAMILY_INET = 1
* IPv4 socket
*
* AF_INET6 = 10
* SOCKET_FAMILY_INET6 = 2
* IPv6 socket
*
* SOCKET_FAMILY_UNIX = 3
* Unix domain socket, will spawn a sockaddr_un which will use the given host as path
* e.g: MVM_io_resolve_host_name(tc, "/run/moarvm.sock", 0, SOCKET_FAMILY_UNIX)
* will spawn an unix domain socket on /run/moarvm.sock
*/
struct sockaddr * MVM_io_resolve_host_name(MVMThreadContext *tc, MVMString *host, MVMint64 port) {

struct sockaddr * MVM_io_resolve_host_name(MVMThreadContext *tc, MVMString *host, MVMint64 port, MVMuint16 family) {
char *host_cstr = MVM_string_utf8_encode_C_string(tc, host);
struct sockaddr *dest;
int error;
struct addrinfo *result;
char port_cstr[8];
unsigned short family = (port >> 16) & USHRT_MAX;
struct addrinfo hints;

#ifndef _WIN32
/* AF_UNIX = 1 */
if (family == AF_UNIX) {
if (family == SOCKET_FAMILY_UNIX) {
struct sockaddr_un *result_un = MVM_malloc(sizeof(struct sockaddr_un));

if (strlen(host_cstr) > 107) {
Expand All @@ -305,7 +305,24 @@ struct sockaddr * MVM_io_resolve_host_name(MVMThreadContext *tc, MVMString *host
}
#endif

hints.ai_family = family;
switch (family) {
case SOCKET_FAMILY_UNSPEC:
hints.ai_family = AF_UNSPEC;
break;
case SOCKET_FAMILY_INET:
hints.ai_family = AF_INET;
break;
case SOCKET_FAMILY_INET6:
hints.ai_family = AF_INET6;
break;
case SOCKET_FAMILY_UNIX:
hints.ai_family = AF_UNIX;
break;
default:
MVM_exception_throw_adhoc(tc, "Unsupported socket family: %hu", family);
break;
}

hints.ai_socktype = 0;
hints.ai_flags = AI_PASSIVE;
hints.ai_protocol = 0;
Expand All @@ -327,7 +344,7 @@ struct sockaddr * MVM_io_resolve_host_name(MVMThreadContext *tc, MVMString *host
}
else {
char *waste[] = { host_cstr, NULL };
MVM_exception_throw_adhoc_free(tc, waste, "Failed to resolve host name '%s' with family %d. Error: '%s'",
MVM_exception_throw_adhoc_free(tc, waste, "Failed to resolve host name '%s' with family %hu. Error: '%s'",
host_cstr, family, gai_strerror(error));
}
freeaddrinfo(result);
Expand All @@ -336,13 +353,13 @@ struct sockaddr * MVM_io_resolve_host_name(MVMThreadContext *tc, MVMString *host
}

/* Establishes a connection. */
static void socket_connect(MVMThreadContext *tc, MVMOSHandle *h, MVMString *host, MVMint64 port) {
static void socket_connect(MVMThreadContext *tc, MVMOSHandle *h, MVMString *host, MVMint64 port, MVMuint16 family) {
MVMIOSyncSocketData *data = (MVMIOSyncSocketData *)h->body.data;
unsigned int interval_id;

interval_id = MVM_telemetry_interval_start(tc, "syncsocket connect");
if (!data->handle) {
struct sockaddr *dest = MVM_io_resolve_host_name(tc, host, port);
struct sockaddr *dest = MVM_io_resolve_host_name(tc, host, port, family);
int r;

Socket s = socket(dest->sa_family , SOCK_STREAM , 0);
Expand Down Expand Up @@ -371,10 +388,10 @@ static void socket_connect(MVMThreadContext *tc, MVMOSHandle *h, MVMString *host
}
}

static void socket_bind(MVMThreadContext *tc, MVMOSHandle *h, MVMString *host, MVMint64 port, MVMint32 backlog) {
static void socket_bind(MVMThreadContext *tc, MVMOSHandle *h, MVMString *host, MVMint64 port, MVMuint16 family, MVMint32 backlog) {
MVMIOSyncSocketData *data = (MVMIOSyncSocketData *)h->body.data;
if (!data->handle) {
struct sockaddr *dest = MVM_io_resolve_host_name(tc, host, port);
struct sockaddr *dest = MVM_io_resolve_host_name(tc, host, port, family);
int r;

Socket s = socket(dest->sa_family , SOCK_STREAM , 0);
Expand Down
9 changes: 8 additions & 1 deletion src/io/syncsocket.h
@@ -1,3 +1,10 @@
typedef enum {
SOCKET_FAMILY_UNSPEC,
SOCKET_FAMILY_INET,
SOCKET_FAMILY_INET6,
SOCKET_FAMILY_UNIX
} MVMSocketFamily;

MVMObject * MVM_io_socket_create(MVMThreadContext *tc, MVMint64 listen);
struct sockaddr * MVM_io_resolve_host_name(MVMThreadContext *tc, MVMString *host, MVMint64 port);
struct sockaddr * MVM_io_resolve_host_name(MVMThreadContext *tc, MVMString *host, MVMint64 port, MVMuint16 family);
MVMString * MVM_io_get_hostname(MVMThreadContext *tc);
6 changes: 4 additions & 2 deletions src/jit/core_templates.expr
Expand Up @@ -1825,7 +1825,8 @@
(carg (tc) ptr)
(carg $0 ptr)
(carg $1 ptr)
(carg $2 int))))
(carg $2 int)
(carg $3 int))))

(template: socket
(call (^func &MVM_io_socket_create)
Expand All @@ -1840,7 +1841,8 @@
(carg $0 ptr)
(carg $1 ptr)
(carg $2 int)
(carg $3 int))))
(carg $3 int)
(carg $4 int))))

(template: accept_sk
(call (^func &MVM_io_accept)
Expand Down