mirror of
https://github.com/janet-lang/janet
synced 2025-06-12 11:34:13 +00:00
Add switch to turn off "reuse" behavior for server sockets.
This commit is contained in:
parent
746ced5501
commit
ba5990ef21
@ -578,9 +578,10 @@ JANET_CORE_FN(cfun_net_connect,
|
|||||||
net_sched_connect(stream);
|
net_sched_connect(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *serverify_socket(JSock sfd) {
|
static const char *serverify_socket(JSock sfd, int reuse) {
|
||||||
/* Set various socket options */
|
/* Set various socket options */
|
||||||
int enable = 1;
|
int enable = 1;
|
||||||
|
if (reuse) {
|
||||||
if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (char *) &enable, sizeof(int)) < 0) {
|
if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (char *) &enable, sizeof(int)) < 0) {
|
||||||
return "setsockopt(SO_REUSEADDR) failed";
|
return "setsockopt(SO_REUSEADDR) failed";
|
||||||
}
|
}
|
||||||
@ -589,6 +590,7 @@ static const char *serverify_socket(JSock sfd) {
|
|||||||
return "setsockopt(SO_REUSEPORT) failed";
|
return "setsockopt(SO_REUSEPORT) failed";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
janet_net_socknoblock(sfd);
|
janet_net_socknoblock(sfd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -642,19 +644,21 @@ JANET_CORE_FN(cfun_net_shutdown,
|
|||||||
}
|
}
|
||||||
|
|
||||||
JANET_CORE_FN(cfun_net_listen,
|
JANET_CORE_FN(cfun_net_listen,
|
||||||
"(net/listen host port &opt type)",
|
"(net/listen host port &opt type no-reuse)",
|
||||||
"Creates a server. Returns a new stream that is neither readable nor "
|
"Creates a server. Returns a new stream that is neither readable nor "
|
||||||
"writeable. Use net/accept or net/accept-loop be to handle connections and start the server. "
|
"writeable. Use net/accept or net/accept-loop be to handle connections and start the server. "
|
||||||
"The type parameter specifies the type of network connection, either "
|
"The type parameter specifies the type of network connection, either "
|
||||||
"a :stream (usually tcp), or :datagram (usually udp). If not specified, the default is "
|
"a :stream (usually tcp), or :datagram (usually udp). If not specified, the default is "
|
||||||
":stream. The host and port arguments are the same as in net/address.") {
|
":stream. The host and port arguments are the same as in net/address. The last boolean parameter `no-reuse` will "
|
||||||
|
"disable the use of SO_REUSEADDR and SO_REUSEPORT when creating a server on some operating systems.") {
|
||||||
janet_sandbox_assert(JANET_SANDBOX_NET_LISTEN);
|
janet_sandbox_assert(JANET_SANDBOX_NET_LISTEN);
|
||||||
janet_arity(argc, 2, 3);
|
janet_arity(argc, 2, 4);
|
||||||
|
|
||||||
/* 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);
|
struct addrinfo *ai = janet_get_addrinfo(argv, 0, socktype, 1, &is_unix);
|
||||||
|
int reuse = !(argc >= 4 && janet_truthy(argv[3]));
|
||||||
|
|
||||||
JSock sfd = JSOCKDEFAULT;
|
JSock sfd = JSOCKDEFAULT;
|
||||||
#ifndef JANET_WINDOWS
|
#ifndef JANET_WINDOWS
|
||||||
@ -664,7 +668,7 @@ JANET_CORE_FN(cfun_net_listen,
|
|||||||
janet_free(ai);
|
janet_free(ai);
|
||||||
janet_panicf("could not create socket: %V", janet_ev_lasterr());
|
janet_panicf("could not create socket: %V", janet_ev_lasterr());
|
||||||
}
|
}
|
||||||
const char *err = serverify_socket(sfd);
|
const char *err = serverify_socket(sfd, reuse);
|
||||||
if (NULL != err || bind(sfd, (struct sockaddr *)ai, sizeof(struct sockaddr_un))) {
|
if (NULL != err || bind(sfd, (struct sockaddr *)ai, sizeof(struct sockaddr_un))) {
|
||||||
JSOCKCLOSE(sfd);
|
JSOCKCLOSE(sfd);
|
||||||
janet_free(ai);
|
janet_free(ai);
|
||||||
@ -687,7 +691,7 @@ JANET_CORE_FN(cfun_net_listen,
|
|||||||
sfd = socket(rp->ai_family, rp->ai_socktype | JSOCKFLAGS, rp->ai_protocol);
|
sfd = socket(rp->ai_family, rp->ai_socktype | JSOCKFLAGS, rp->ai_protocol);
|
||||||
#endif
|
#endif
|
||||||
if (!JSOCKVALID(sfd)) continue;
|
if (!JSOCKVALID(sfd)) continue;
|
||||||
const char *err = serverify_socket(sfd);
|
const char *err = serverify_socket(sfd, reuse);
|
||||||
if (NULL != err) {
|
if (NULL != err) {
|
||||||
JSOCKCLOSE(sfd);
|
JSOCKCLOSE(sfd);
|
||||||
continue;
|
continue;
|
||||||
|
@ -410,6 +410,10 @@
|
|||||||
(ev/call handler connection)
|
(ev/call handler connection)
|
||||||
(break))))
|
(break))))
|
||||||
|
|
||||||
|
# Make sure we can't bind again with no-reuse
|
||||||
|
(assert-error "no-reuse"
|
||||||
|
(net/listen test-host test-port :stream true))
|
||||||
|
|
||||||
# Read from socket
|
# Read from socket
|
||||||
|
|
||||||
(defn expect-read
|
(defn expect-read
|
||||||
|
Loading…
x
Reference in New Issue
Block a user