mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-04-07 11:08:36 +00:00
Fix bugs revealed by 'rhizomeprotocol' test
Was not transmitting actual HTTP server port in rhizome announcements, was always transmitting port 4110. When trying for a free HTTP server port, sometimes bind() succeeds but listen() fails with EADDRINUSE, so new logic to deal with that.
This commit is contained in:
parent
e69abc3198
commit
d111f763c7
@ -859,7 +859,7 @@ int overlay_tick_interface(int i, long long now)
|
||||
overlay_stuff_packet_from_queue(i,e,OQ_ORDINARY,now,pax,&frame_pax,MAX_FRAME_PAX);
|
||||
overlay_stuff_packet_from_queue(i,e,OQ_OPPORTUNISTIC,now,pax,&frame_pax,MAX_FRAME_PAX);
|
||||
/* 5. XXX Fill the packet up to a suitable size with anything that seems a good idea */
|
||||
if (rhizome_enabled())
|
||||
if (rhizome_enabled() && rhizome_http_server_running())
|
||||
overlay_rhizome_add_advertisements(i,e);
|
||||
|
||||
if (debug&DEBUG_PACKETCONSTRUCTION)
|
||||
|
@ -128,6 +128,7 @@ typedef struct rhizome_manifest {
|
||||
|
||||
extern long long rhizome_space;
|
||||
extern int rhizome_fetch_interval_ms;
|
||||
extern unsigned short rhizome_http_server_port;
|
||||
|
||||
int rhizome_configure();
|
||||
|
||||
|
101
rhizome_http.c
101
rhizome_http.c
@ -89,9 +89,9 @@ struct profile_total connection_stats;
|
||||
|
||||
/*
|
||||
HTTP server and client code for rhizome transfers.
|
||||
|
||||
*/
|
||||
|
||||
unsigned short rhizome_http_server_port = 0;
|
||||
static int rhizome_server_socket = -1;
|
||||
static long long rhizome_server_last_start_attempt = -1;
|
||||
|
||||
@ -120,6 +120,11 @@ unsigned char favicon_bytes[]={
|
||||
,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
int favicon_len=318;
|
||||
|
||||
int rhizome_http_server_running()
|
||||
{
|
||||
return rhizome_server_socket != -1;
|
||||
}
|
||||
|
||||
/* Start the Rhizome HTTP server by creating a socket, binding it to an available port, and
|
||||
marking it as passive. If called repeatedly and frequently, this function will only try to start
|
||||
the server after a certain time has elapsed since the last attempt.
|
||||
@ -141,54 +146,62 @@ int rhizome_http_server_start()
|
||||
if (debug&DEBUG_RHIZOME)
|
||||
DEBUGF("Starting rhizome HTTP server");
|
||||
|
||||
rhizome_server_socket = socket(AF_INET,SOCK_STREAM,0);
|
||||
if (rhizome_server_socket == -1) {
|
||||
WHY_perror("socket");
|
||||
return WHY("Failed to start rhizome HTTP server");
|
||||
}
|
||||
|
||||
int on=1;
|
||||
if (setsockopt(rhizome_server_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) == -1) {
|
||||
WHY_perror("setsockopt(REUSEADDR)");
|
||||
close(rhizome_server_socket);
|
||||
rhizome_server_socket = -1;
|
||||
return WHY("Failed to start rhizome HTTP server");
|
||||
}
|
||||
|
||||
/* Starting at the default port, look for a free port to bind to. */
|
||||
struct sockaddr_in address;
|
||||
bzero((char *) &address, sizeof(address));
|
||||
address.sin_family = AF_INET;
|
||||
address.sin_addr.s_addr = INADDR_ANY;
|
||||
int port = RHIZOME_HTTP_PORT;
|
||||
int result = -1;
|
||||
do {
|
||||
unsigned short port;
|
||||
for (port = RHIZOME_HTTP_PORT; port <= RHIZOME_HTTP_PORT_MAX; ++port) {
|
||||
/* Create a new socket, reusable and non-blocking. */
|
||||
if (rhizome_server_socket == -1) {
|
||||
rhizome_server_socket = socket(AF_INET,SOCK_STREAM,0);
|
||||
if (rhizome_server_socket == -1) {
|
||||
WHY_perror("socket");
|
||||
goto error;
|
||||
}
|
||||
int on=1;
|
||||
if (setsockopt(rhizome_server_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) == -1) {
|
||||
WHY_perror("setsockopt(REUSEADDR)");
|
||||
goto error;
|
||||
}
|
||||
if (ioctl(rhizome_server_socket, FIONBIO, (char *)&on) == -1) {
|
||||
WHY_perror("ioctl(FIONBIO)");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
/* Bind it to the next port we want to try. */
|
||||
struct sockaddr_in address;
|
||||
bzero((char *) &address, sizeof(address));
|
||||
address.sin_family = AF_INET;
|
||||
address.sin_addr.s_addr = INADDR_ANY;
|
||||
address.sin_port = htons(port);
|
||||
result = bind(rhizome_server_socket, (struct sockaddr *) &address, sizeof(address));
|
||||
} while (result == -1 && errno == EADDRINUSE && ++port <= RHIZOME_HTTP_PORT_MAX);
|
||||
if (result == -1) {
|
||||
WHY_perror("bind");
|
||||
if (bind(rhizome_server_socket, (struct sockaddr *) &address, sizeof(address)) == -1) {
|
||||
if (errno != EADDRINUSE) {
|
||||
WHY_perror("bind");
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
/* We bound to a port. The battle is half won. Now we have to successfully listen on that
|
||||
port, which could also fail with EADDRINUSE, in which case we have to scrap the socket and
|
||||
create a new one, because once bound, a socket stays bound.
|
||||
*/
|
||||
if (listen(rhizome_server_socket, 20) != -1)
|
||||
goto success;
|
||||
if (errno != EADDRINUSE) {
|
||||
WHY_perror("listen");
|
||||
goto error;
|
||||
}
|
||||
close(rhizome_server_socket);
|
||||
rhizome_server_socket = -1;
|
||||
}
|
||||
}
|
||||
WHYF("No ports available in range %u to %u", RHIZOME_HTTP_PORT, RHIZOME_HTTP_PORT_MAX);
|
||||
error:
|
||||
if (rhizome_server_socket != -1) {
|
||||
close(rhizome_server_socket);
|
||||
rhizome_server_socket = -1;
|
||||
return WHY("Failed to start rhizome HTTP server");
|
||||
}
|
||||
|
||||
if (ioctl(rhizome_server_socket, FIONBIO, (char *)&on) == -1) {
|
||||
WHY_perror("ioctl(FIONBIO)");
|
||||
close(rhizome_server_socket);
|
||||
rhizome_server_socket = -1;
|
||||
return WHY("Failed to start rhizome HTTP server");
|
||||
}
|
||||
|
||||
if (listen(rhizome_server_socket, 20) == -1) {
|
||||
WHY_perror("listen");
|
||||
close(rhizome_server_socket);
|
||||
rhizome_server_socket = -1;
|
||||
return WHY("Failed to start rhizome HTTP server");
|
||||
}
|
||||
return WHY("Failed to start rhizome HTTP server");
|
||||
|
||||
success:
|
||||
INFOF("Started Rhizome HTTP server on port %d, fd = %d", port, rhizome_server_socket);
|
||||
|
||||
rhizome_http_server_port = port;
|
||||
/* Add Rhizome HTTPd server to list of file descriptors to watch */
|
||||
server_alarm.function = rhizome_server_poll;
|
||||
server_stats.name="rhizome_server_poll";
|
||||
@ -196,8 +209,8 @@ int rhizome_http_server_start()
|
||||
server_alarm.poll.fd = rhizome_server_socket;
|
||||
server_alarm.poll.events = POLLIN;
|
||||
watch(&server_alarm);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void rhizome_client_poll(struct sched_ent *alarm)
|
||||
|
@ -76,7 +76,6 @@ int overlay_rhizome_add_advertisements(int interface_number,overlay_buffer *e)
|
||||
{
|
||||
IN();
|
||||
int voice_mode=0;
|
||||
unsigned short int http_port = RHIZOME_HTTP_PORT;
|
||||
|
||||
/* behave differently during voice mode.
|
||||
Basically don't encourage people to grab stuff from us, but keep
|
||||
@ -130,7 +129,7 @@ int overlay_rhizome_add_advertisements(int interface_number,overlay_buffer *e)
|
||||
*/
|
||||
ob_append_byte(e,3+skipmanifests);
|
||||
/* Rhizome HTTP server port number (2 bytes) */
|
||||
ob_append_short(e, http_port);
|
||||
ob_append_short(e, rhizome_http_server_port);
|
||||
|
||||
/* XXX Should add priority bundles here.
|
||||
XXX Should prioritise bundles for subscribed groups, Serval-authorised files
|
||||
|
1
serval.h
1
serval.h
@ -155,6 +155,7 @@ extern int returnMultiVars;
|
||||
extern char *gatewayspec;
|
||||
|
||||
int rhizome_enabled();
|
||||
int rhizome_http_server_running();
|
||||
const char *rhizome_datastore_path();
|
||||
|
||||
extern struct in_addr client_addr;
|
||||
|
@ -28,7 +28,6 @@ teardown() {
|
||||
stop_all_servald_servers
|
||||
kill_all_servald_processes
|
||||
assert_no_servald_processes
|
||||
tfw_cat $LOGA $LOGB
|
||||
}
|
||||
|
||||
setup_rhizome() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user