mirror of
https://github.com/janet-lang/janet
synced 2024-11-28 19:19:53 +00:00
Fix incorrect code that created socket twice.
This commit is contained in:
parent
d8f6fbf594
commit
24f97510b0
106
src/core/net.c
106
src/core/net.c
@ -261,7 +261,7 @@ static int janet_get_sockettype(Janet *argv, int32_t argc, int32_t n) {
|
|||||||
/* Needs argc >= offset + 2 */
|
/* Needs argc >= offset + 2 */
|
||||||
/* For unix paths, just rertuns a single sockaddr and sets *is_unix to 1,
|
/* For unix paths, just rertuns a single sockaddr and sets *is_unix to 1,
|
||||||
* otherwise 0. Also, ignores is_bind when is a unix socket. */
|
* otherwise 0. Also, ignores is_bind when is a unix socket. */
|
||||||
static struct addrinfo *janet_get_addrinfo(Janet *argv, int32_t offset, int socktype, int passive, int *is_unix, int is_bind) {
|
static struct addrinfo *janet_get_addrinfo(Janet *argv, int32_t offset, int socktype, int passive, int *is_unix) {
|
||||||
/* Unix socket support - not yet supported on windows. */
|
/* Unix socket support - not yet supported on windows. */
|
||||||
#ifndef JANET_WINDOWS
|
#ifndef JANET_WINDOWS
|
||||||
if (janet_keyeq(argv[offset], "unix")) {
|
if (janet_keyeq(argv[offset], "unix")) {
|
||||||
@ -286,24 +286,12 @@ static struct addrinfo *janet_get_addrinfo(Janet *argv, int32_t offset, int sock
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* Get host and port */
|
/* Get host and port */
|
||||||
char *host = NULL, *port = NULL;
|
char *host = (char *)janet_getcstring(argv, offset);
|
||||||
char *err = NULL;
|
char *port = NULL;
|
||||||
/* if is_bind is set, skip offsets and ports! */
|
if (janet_checkint(argv[offset + 1])) {
|
||||||
if (!is_bind) {
|
port = (char *)janet_to_string(argv[offset + 1]);
|
||||||
host = (char *)janet_getcstring(argv, offset);
|
|
||||||
if (janet_checkint(argv[offset + 1])) {
|
|
||||||
port = (char *)janet_to_string(argv[offset + 1]);
|
|
||||||
} else {
|
|
||||||
port = (char *)janet_optcstring(argv, offset + 2, offset + 1, NULL);
|
|
||||||
}
|
|
||||||
err = "could not get address info: %s";
|
|
||||||
} else {
|
} else {
|
||||||
/* when is_bind is set, we're performing a connect, but wanting to
|
port = (char *)janet_optcstring(argv, offset + 2, offset + 1, NULL);
|
||||||
* specify from where we connect, and in general don't care about a
|
|
||||||
* port */
|
|
||||||
host = (char *)janet_getcstring(argv, 3);
|
|
||||||
port = NULL;
|
|
||||||
err = "could not get address info for connect bind: %s";
|
|
||||||
}
|
}
|
||||||
/* getaddrinfo */
|
/* getaddrinfo */
|
||||||
struct addrinfo *ai = NULL;
|
struct addrinfo *ai = NULL;
|
||||||
@ -314,7 +302,7 @@ static struct addrinfo *janet_get_addrinfo(Janet *argv, int32_t offset, int sock
|
|||||||
hints.ai_flags = passive ? AI_PASSIVE : 0;
|
hints.ai_flags = passive ? AI_PASSIVE : 0;
|
||||||
int status = getaddrinfo(host, port, &hints, &ai);
|
int status = getaddrinfo(host, port, &hints, &ai);
|
||||||
if (status) {
|
if (status) {
|
||||||
janet_panicf(err, gai_strerror(status));
|
janet_panicf("could not get address info: %s", gai_strerror(status));
|
||||||
}
|
}
|
||||||
*is_unix = 0;
|
*is_unix = 0;
|
||||||
return ai;
|
return ai;
|
||||||
@ -335,7 +323,7 @@ JANET_CORE_FN(cfun_net_sockaddr,
|
|||||||
int socktype = janet_get_sockettype(argv, argc, 2);
|
int socktype = janet_get_sockettype(argv, argc, 2);
|
||||||
int is_unix = 0;
|
int is_unix = 0;
|
||||||
int make_arr = (argc >= 3 && janet_truthy(argv[3]));
|
int make_arr = (argc >= 3 && janet_truthy(argv[3]));
|
||||||
struct addrinfo *ai = janet_get_addrinfo(argv, 0, socktype, 0, &is_unix, 0);
|
struct addrinfo *ai = janet_get_addrinfo(argv, 0, socktype, 0, &is_unix);
|
||||||
#ifndef JANET_WINDOWS
|
#ifndef JANET_WINDOWS
|
||||||
/* no unix domain socket support on windows yet */
|
/* no unix domain socket support on windows yet */
|
||||||
if (is_unix) {
|
if (is_unix) {
|
||||||
@ -370,24 +358,47 @@ JANET_CORE_FN(cfun_net_sockaddr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
JANET_CORE_FN(cfun_net_connect,
|
JANET_CORE_FN(cfun_net_connect,
|
||||||
"(net/connect host port &opt type bindhost)",
|
"(net/connect host port &opt type bindhost bindport)",
|
||||||
"Open a connection to communicate with a server. Returns a duplex stream "
|
"Open a connection to communicate with a server. Returns a duplex stream "
|
||||||
"that can be used to communicate with the server. Type is an optional keyword "
|
"that can be used to communicate with the server. Type is an optional keyword "
|
||||||
"to specify a connection type, either :stream or :datagram. The default is :stream. "
|
"to specify a connection type, either :stream or :datagram. The default is :stream. "
|
||||||
"Bindhost is an optional string to select from what address to make the outgoing "
|
"Bindhost is an optional string to select from what address to make the outgoing "
|
||||||
"connection, with the default being the same as using the OS's preferred address. ") {
|
"connection, with the default being the same as using the OS's preferred address. ") {
|
||||||
janet_arity(argc, 2, 4);
|
janet_arity(argc, 2, 5);
|
||||||
|
|
||||||
|
/* Check arguments */
|
||||||
int socktype = janet_get_sockettype(argv, argc, 2);
|
int socktype = janet_get_sockettype(argv, argc, 2);
|
||||||
int is_unix = 0;
|
int is_unix = 0;
|
||||||
|
const char *bindhost = janet_optcstring(argv, argc, 3, NULL);
|
||||||
|
int bindport = 0;
|
||||||
|
if (janet_checkint(argv[4])) {
|
||||||
|
bindport = janet_unwrap_integer(argv[4]);
|
||||||
|
} else {
|
||||||
|
const char *portstring = (char *)janet_optcstring(argv, argc, 4, "0");
|
||||||
|
bindport = atoi(portstring);
|
||||||
|
}
|
||||||
|
|
||||||
/* Where we're connecting to */
|
/* Where we're connecting to */
|
||||||
struct addrinfo *ai = janet_get_addrinfo(argv, 0, socktype, 0, &is_unix, 0);
|
struct addrinfo *ai = janet_get_addrinfo(argv, 0, socktype, 0, &is_unix);
|
||||||
|
|
||||||
/* Check if we're binding address */
|
/* Check if we're binding address */
|
||||||
struct addrinfo *binding = NULL;
|
struct addrinfo *binding = NULL;
|
||||||
if (argc > 3 && is_unix == 0 && !janet_checktype(argv[3], JANET_NIL)) {
|
if (bindhost != NULL) {
|
||||||
int is_bindhost_unix = 0; /* discarded value */
|
if (is_unix) {
|
||||||
binding = janet_get_addrinfo(argv, 0, socktype, 0, &is_bindhost_unix, 1);
|
freeaddrinfo(ai);
|
||||||
|
janet_panic("bindhost not supported for unix domain sockets");
|
||||||
|
}
|
||||||
|
/* getaddrinfo */
|
||||||
|
struct addrinfo hints;
|
||||||
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_family = AF_INET;
|
||||||
|
hints.ai_socktype = socktype;
|
||||||
|
hints.ai_flags = 0;
|
||||||
|
int status = getaddrinfo(bindhost, NULL, &hints, &binding);
|
||||||
|
if (status) {
|
||||||
|
freeaddrinfo(ai);
|
||||||
|
janet_panicf("could not get address info for bindhost: %s", gai_strerror(status));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create socket */
|
/* Create socket */
|
||||||
@ -398,7 +409,9 @@ JANET_CORE_FN(cfun_net_connect,
|
|||||||
if (is_unix) {
|
if (is_unix) {
|
||||||
sock = socket(AF_UNIX, socktype | JSOCKFLAGS, 0);
|
sock = socket(AF_UNIX, socktype | JSOCKFLAGS, 0);
|
||||||
if (!JSOCKVALID(sock)) {
|
if (!JSOCKVALID(sock)) {
|
||||||
janet_panicf("could not create socket: %V", janet_ev_lasterr());
|
Janet v = janet_ev_lasterr();
|
||||||
|
janet_free(ai);
|
||||||
|
janet_panicf("could not create socket: %V", v);
|
||||||
}
|
}
|
||||||
addr = (void *) ai;
|
addr = (void *) ai;
|
||||||
addrlen = sizeof(struct sockaddr_un);
|
addrlen = sizeof(struct sockaddr_un);
|
||||||
@ -419,39 +432,36 @@ JANET_CORE_FN(cfun_net_connect,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (NULL == addr) {
|
if (NULL == addr) {
|
||||||
|
Janet v = janet_ev_lasterr();
|
||||||
freeaddrinfo(ai);
|
freeaddrinfo(ai);
|
||||||
janet_panicf("could not create socket: %V", janet_ev_lasterr());
|
janet_panicf("could not create socket: %V", v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Perform bind if binding */
|
/* Bind to bindhost and bindport if given */
|
||||||
if (binding != NULL) {
|
if (bindhost != NULL) {
|
||||||
/* Check all addrinfos in a loop for the first that we can bind to. */
|
/* Bind to a specific network interface (and optionally a specific local port) */
|
||||||
struct addrinfo *rp = NULL;
|
struct sockaddr_in localaddr;
|
||||||
for (rp = binding; rp != NULL; rp = rp->ai_next) {
|
memset(&localaddr, 0, sizeof(localaddr));
|
||||||
#ifdef JANET_WINDOWS
|
localaddr.sin_family = AF_INET;
|
||||||
sock = WSASocketW(rp->ai_family, rp->ai_socktype | JSOCKFLAGS, rp->ai_protocol, NULL, 0, WSA_FLAG_OVERLAPPED);
|
localaddr.sin_addr.s_addr = inet_addr(bindhost);
|
||||||
#else
|
localaddr.sin_port = bindport;
|
||||||
sock = socket(rp->ai_family, rp->ai_socktype | JSOCKFLAGS, rp->ai_protocol);
|
if (0 == bind(sock, (struct sockaddr *)&localaddr, sizeof(localaddr))) {
|
||||||
#endif
|
Janet lasterr = janet_ev_lasterr();
|
||||||
if (!JSOCKVALID(sock)) continue;
|
freeaddrinfo(ai);
|
||||||
|
|
||||||
/* Bind */
|
|
||||||
if (bind(sock, rp->ai_addr, (int) rp->ai_addrlen) == 0) break;
|
|
||||||
JSOCKCLOSE(sock);
|
JSOCKCLOSE(sock);
|
||||||
}
|
janet_panicf("could not bind outgoing address: %V", lasterr);
|
||||||
freeaddrinfo(binding);
|
|
||||||
if (NULL == rp) {
|
|
||||||
janet_panicf("could not bind outgoing address: %V", janet_ev_lasterr());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Connect to socket */
|
/* Connect to socket */
|
||||||
#ifdef JANET_WINDOWS
|
#ifdef JANET_WINDOWS
|
||||||
int status = WSAConnect(sock, addr, addrlen, NULL, NULL, NULL, NULL);
|
int status = WSAConnect(sock, addr, addrlen, NULL, NULL, NULL, NULL);
|
||||||
|
Janet lasterr = janet_ev_lasterr();
|
||||||
freeaddrinfo(ai);
|
freeaddrinfo(ai);
|
||||||
#else
|
#else
|
||||||
int status = connect(sock, addr, addrlen);
|
int status = connect(sock, addr, addrlen);
|
||||||
|
Janet lasterr = janet_ev_lasterr();
|
||||||
if (is_unix) {
|
if (is_unix) {
|
||||||
janet_free(ai);
|
janet_free(ai);
|
||||||
} else {
|
} else {
|
||||||
@ -461,7 +471,7 @@ JANET_CORE_FN(cfun_net_connect,
|
|||||||
|
|
||||||
if (status == -1) {
|
if (status == -1) {
|
||||||
JSOCKCLOSE(sock);
|
JSOCKCLOSE(sock);
|
||||||
janet_panicf("could not connect to socket: %V", janet_ev_lasterr());
|
janet_panicf("could not connect socket: %V", lasterr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up the socket for non-blocking IO after connect - TODO - non-blocking connect? */
|
/* Set up the socket for non-blocking IO after connect - TODO - non-blocking connect? */
|
||||||
@ -547,7 +557,7 @@ JANET_CORE_FN(cfun_net_listen,
|
|||||||
/* Get host, port, and handler*/
|
/* Get host, port, and handler*/
|
||||||
int socktype = janet_get_sockettype(argv, argc, 2);
|
int socktype = janet_get_sockettype(argv, argc, 2);
|
||||||
int is_unix = 0;
|
int is_unix = 0;
|
||||||
struct addrinfo *ai = janet_get_addrinfo(argv, 0, socktype, 1, &is_unix, 0);
|
struct addrinfo *ai = janet_get_addrinfo(argv, 0, socktype, 1, &is_unix);
|
||||||
|
|
||||||
JSock sfd = JSOCKDEFAULT;
|
JSock sfd = JSOCKDEFAULT;
|
||||||
#ifndef JANET_WINDOWS
|
#ifndef JANET_WINDOWS
|
||||||
|
Loading…
Reference in New Issue
Block a user