mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-18 20:57:56 +00:00
Refactor socket name and address length handling
This commit is contained in:
parent
5ea19ab538
commit
0d5d878521
168
commandline.c
168
commandline.c
@ -931,9 +931,6 @@ int app_mdp_ping(const struct cli_parsed *parsed, struct cli_context *context)
|
||||
int64_t interval_ms = 1000;
|
||||
str_to_uint64_interval_ms(opt_interval, &interval_ms, NULL);
|
||||
|
||||
overlay_mdp_frame mdp;
|
||||
bzero(&mdp, sizeof(overlay_mdp_frame));
|
||||
|
||||
/* First sequence number in the echo frames */
|
||||
unsigned int firstSeq=random();
|
||||
unsigned int sequence_number=firstSeq;
|
||||
@ -941,22 +938,23 @@ int app_mdp_ping(const struct cli_parsed *parsed, struct cli_context *context)
|
||||
int broadcast = is_sid_t_broadcast(ping_sid);
|
||||
|
||||
/* Bind to MDP socket and await confirmation */
|
||||
if ((mdp_sockfd = overlay_mdp_client_socket()) < 0)
|
||||
if ((mdp_sockfd = mdp_socket()) < 0)
|
||||
return WHY("Cannot create MDP socket");
|
||||
|
||||
sid_t srcsid;
|
||||
mdp_port_t port=32768+(random()&32767);
|
||||
if (overlay_mdp_getmyaddr(mdp_sockfd, 0, &srcsid)) {
|
||||
overlay_mdp_client_close(mdp_sockfd);
|
||||
return WHY("Could not get local address");
|
||||
}
|
||||
if (overlay_mdp_bind(mdp_sockfd, &srcsid, port)) {
|
||||
overlay_mdp_client_close(mdp_sockfd);
|
||||
return WHY("Could not bind to MDP socket");
|
||||
}
|
||||
struct mdp_header mdp_header;
|
||||
bzero(&mdp_header, sizeof(mdp_header));
|
||||
|
||||
mdp_header.local.sid = BIND_PRIMARY;
|
||||
mdp_header.remote.sid = ping_sid;
|
||||
mdp_header.remote.port = MDP_PORT_ECHO;
|
||||
mdp_header.qos = OQ_MESH_MANAGEMENT;
|
||||
mdp_header.ttl = PAYLOAD_TTL_DEFAULT;
|
||||
mdp_header.flags = MDP_FLAG_BIND;
|
||||
if (broadcast)
|
||||
mdp_header.flags |= MDP_FLAG_NO_CRYPT;
|
||||
|
||||
/* TODO Eventually we should try to resolve SID to phone number and vice versa */
|
||||
cli_printf(context, "MDP PING %s (%s): 12 data bytes", alloca_tohex_sid_t(ping_sid), alloca_tohex_sid_t(ping_sid));
|
||||
cli_printf(context, "MDP PING %s: 12 data bytes", alloca_tohex_sid_t(ping_sid));
|
||||
cli_delim(context, "\n");
|
||||
cli_flush(context);
|
||||
|
||||
@ -968,81 +966,91 @@ int app_mdp_ping(const struct cli_parsed *parsed, struct cli_context *context)
|
||||
|
||||
if (broadcast)
|
||||
WARN("broadcast ping packets will not be encrypted");
|
||||
|
||||
for (; icount==0 || tx_count<icount; ++sequence_number) {
|
||||
/* Now send the ping packets */
|
||||
mdp.packetTypeAndFlags=MDP_TX;
|
||||
if (broadcast) mdp.packetTypeAndFlags|=MDP_NOCRYPT;
|
||||
mdp.out.src.port=port;
|
||||
mdp.out.src.sid = srcsid;
|
||||
mdp.out.dst.sid = ping_sid;
|
||||
mdp.out.queue=OQ_MESH_MANAGEMENT;
|
||||
/* Set port to well known echo port */
|
||||
mdp.out.dst.port=MDP_PORT_ECHO;
|
||||
mdp.out.payload_length=4+8;
|
||||
int *seq=(int *)&mdp.out.payload;
|
||||
*seq=sequence_number;
|
||||
write_uint64(&mdp.out.payload[4], gettime_ms());
|
||||
|
||||
int res=overlay_mdp_send(mdp_sockfd, &mdp, 0, 0);
|
||||
if (res) {
|
||||
WHYF("could not dispatch PING frame #%d (error %d)%s%s",
|
||||
sequence_number - firstSeq,
|
||||
res,
|
||||
mdp.packetTypeAndFlags == MDP_ERROR ? ": " : "",
|
||||
mdp.packetTypeAndFlags == MDP_ERROR ? mdp.error.message : ""
|
||||
);
|
||||
} else
|
||||
tx_count++;
|
||||
|
||||
// send a ping packet
|
||||
{
|
||||
uint8_t payload[12];
|
||||
int *seq=(int *)payload;
|
||||
*seq=sequence_number;
|
||||
write_uint64(&payload[4], gettime_ms());
|
||||
|
||||
int r = mdp_send(mdp_sockfd, &mdp_header, payload, sizeof(payload));
|
||||
if (r<0)
|
||||
WHY_perror("mdp_send");
|
||||
else
|
||||
tx_count++;
|
||||
}
|
||||
|
||||
/* Now look for replies until one second has passed, and print any replies
|
||||
with appropriate information as required */
|
||||
time_ms_t now = gettime_ms();
|
||||
time_ms_t finish = now + (tx_count < icount?interval_ms:timeout_ms);
|
||||
for (; !servalShutdown && now < finish; now = gettime_ms()) {
|
||||
time_ms_t poll_timeout_ms = finish - gettime_ms();
|
||||
int result = overlay_mdp_client_poll(mdp_sockfd, poll_timeout_ms);
|
||||
|
||||
if (result>0) {
|
||||
int ttl=-1;
|
||||
if (overlay_mdp_recv(mdp_sockfd, &mdp, port, &ttl)==0) {
|
||||
switch(mdp.packetTypeAndFlags&MDP_TYPE_MASK) {
|
||||
case MDP_ERROR:
|
||||
WHYF("mdpping: overlay_mdp_recv: %s (code %d)", mdp.error.message, mdp.error.error);
|
||||
break;
|
||||
case MDP_TX:
|
||||
{
|
||||
int *rxseq=(int *)&mdp.in.payload;
|
||||
time_ms_t txtime = read_uint64(&mdp.in.payload[4]);
|
||||
int hop_count = 64 - mdp.in.ttl;
|
||||
time_ms_t delay = gettime_ms() - txtime;
|
||||
cli_printf(context, "%s: seq=%d time=%"PRId64"ms hops=%d %s%s",
|
||||
alloca_tohex_sid_t(mdp.in.src.sid),
|
||||
(*rxseq)-firstSeq+1,
|
||||
(int64_t)delay,
|
||||
hop_count,
|
||||
mdp.packetTypeAndFlags&MDP_NOCRYPT?"":" ENCRYPTED",
|
||||
mdp.packetTypeAndFlags&MDP_NOSIGN?"":" SIGNED");
|
||||
cli_delim(context, "\n");
|
||||
cli_flush(context);
|
||||
// TODO Put duplicate pong detection here so that stats work properly.
|
||||
rx_count++;
|
||||
ret=0;
|
||||
rx_ms+=delay;
|
||||
if (rx_mintime>delay||rx_mintime==-1) rx_mintime=delay;
|
||||
if (delay>rx_maxtime) rx_maxtime=delay;
|
||||
rx_times[rx_count%1024]=delay;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
WHYF("mdpping: overlay_mdp_recv: Unexpected MDP frame type 0x%x", mdp.packetTypeAndFlags);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mdp_poll(mdp_sockfd, poll_timeout_ms)<=0)
|
||||
continue;
|
||||
|
||||
struct mdp_header mdp_recv_header;
|
||||
uint8_t recv_payload[12];
|
||||
ssize_t len = mdp_recv(mdp_sockfd, &mdp_recv_header, recv_payload, sizeof(recv_payload));
|
||||
|
||||
if (len<0){
|
||||
WHY_perror("mdp_recv");
|
||||
break;
|
||||
}
|
||||
|
||||
if (mdp_recv_header.flags & MDP_FLAG_ERROR){
|
||||
WHY("Serval daemon reported an error, please check the log for more information");
|
||||
break;
|
||||
}
|
||||
|
||||
if (mdp_recv_header.flags & MDP_FLAG_BIND){
|
||||
// received port binding confirmation
|
||||
mdp_header.local = mdp_recv_header.local;
|
||||
mdp_header.flags &= ~MDP_FLAG_BIND;
|
||||
DEBUGF("Bound to %s:%d", alloca_tohex_sid_t(mdp_header.local.sid), mdp_header.local.port);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (len<sizeof(recv_payload)){
|
||||
DEBUGF("Ignoring ping response as it is too short");
|
||||
continue;
|
||||
}
|
||||
|
||||
int *rxseq=(int *)&recv_payload;
|
||||
time_ms_t txtime = read_uint64(&recv_payload[4]);
|
||||
int hop_count = 64 - mdp_recv_header.ttl;
|
||||
time_ms_t delay = gettime_ms() - txtime;
|
||||
|
||||
cli_put_hexvalue(context, mdp_recv_header.remote.sid.binary, SID_SIZE, ": seq=");
|
||||
cli_put_long(context, (*rxseq)-firstSeq+1, " time=");
|
||||
cli_put_long(context, delay, "ms hops=");
|
||||
cli_put_long(context, hop_count, "");
|
||||
|
||||
if (mdp_recv_header.flags&MDP_FLAG_NO_CRYPT)
|
||||
cli_put_string(context, "", "");
|
||||
else
|
||||
cli_put_string(context, " ENCRYPTED", "");
|
||||
|
||||
if (mdp_recv_header.flags&MDP_FLAG_NO_SIGN)
|
||||
cli_put_string(context, "", "\n");
|
||||
else
|
||||
cli_put_string(context, " SIGNED", "\n");
|
||||
cli_flush(context);
|
||||
// TODO Put duplicate pong detection here so that stats work properly.
|
||||
rx_count++;
|
||||
ret=0;
|
||||
rx_ms+=delay;
|
||||
if (rx_mintime>delay||rx_mintime==-1) rx_mintime=delay;
|
||||
if (delay>rx_maxtime) rx_maxtime=delay;
|
||||
rx_times[rx_count%1024]=delay;
|
||||
}
|
||||
}
|
||||
|
||||
overlay_mdp_client_close(mdp_sockfd);
|
||||
mdp_close(mdp_sockfd);
|
||||
|
||||
{
|
||||
float rx_stddev=0;
|
||||
@ -2264,7 +2272,7 @@ static int handle_pins(const struct cli_parsed *parsed, struct cli_context *cont
|
||||
WHYF("Timeout while waiting for response");
|
||||
break;
|
||||
}
|
||||
if (rev_header.flags & MDP_FLAG_OK){
|
||||
if (rev_header.flags & MDP_FLAG_CLOSE){
|
||||
ret=0;
|
||||
break;
|
||||
}
|
||||
@ -2334,7 +2342,7 @@ int app_id_list(const struct cli_parsed *parsed, struct cli_context *context)
|
||||
// TODO receive and decode other details about this identity
|
||||
}
|
||||
|
||||
if (rev_header.flags & MDP_FLAG_OK){
|
||||
if (rev_header.flags & MDP_FLAG_CLOSE){
|
||||
ret=0;
|
||||
break;
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ static void directory_send(struct subscriber *directory_service, const sid_t *si
|
||||
// Used by tests
|
||||
INFOF("Sending directory registration for %s*, %s, %s to %s*",
|
||||
alloca_tohex_sid_t_trunc(*sidp, 14), did, name, alloca_tohex_sid_t_trunc(directory_service->sid, 14));
|
||||
overlay_mdp_dispatch(&request, 0, NULL, 0);
|
||||
overlay_mdp_dispatch(&request, NULL);
|
||||
}
|
||||
|
||||
// send a registration packet for each unlocked identity
|
||||
|
@ -6,6 +6,7 @@ HDRS= fifo.h \
|
||||
rhizome.h \
|
||||
serval.h \
|
||||
keyring.h \
|
||||
socket.h \
|
||||
cli.h \
|
||||
str.h \
|
||||
rotbuf.h \
|
||||
|
10
keyring.c
10
keyring.c
@ -1764,7 +1764,7 @@ static int keyring_respond_sas(keyring_file *k, overlay_mdp_frame *req)
|
||||
alloca_tohex_sid_t(req->out.src.sid), req->out.src.port,
|
||||
alloca_tohex_sid_t(req->out.dst.sid), req->out.dst.port
|
||||
);
|
||||
return overlay_mdp_dispatch(req,0,NULL,0);
|
||||
return overlay_mdp_dispatch(req, NULL);
|
||||
}
|
||||
|
||||
// someone else is claiming to be me on this network
|
||||
@ -1790,7 +1790,7 @@ int keyring_send_unlock(struct subscriber *subscriber)
|
||||
if (crypto_sign_message(subscriber, mdp.out.payload, sizeof(mdp.out.payload), &len))
|
||||
return -1;
|
||||
mdp.out.payload_length=len;
|
||||
return overlay_mdp_dispatch(&mdp, 0 /* system generated */, NULL, 0);
|
||||
return overlay_mdp_dispatch(&mdp, NULL);
|
||||
}
|
||||
|
||||
static int keyring_send_challenge(struct subscriber *source, struct subscriber *dest)
|
||||
@ -1815,7 +1815,7 @@ static int keyring_send_challenge(struct subscriber *source, struct subscriber *
|
||||
bcopy(source->identity->challenge, &mdp.out.payload[1], sizeof(source->identity->challenge));
|
||||
mdp.out.payload_length+=sizeof(source->identity->challenge);
|
||||
|
||||
return overlay_mdp_dispatch(&mdp, 0 /* system generated */, NULL, 0);
|
||||
return overlay_mdp_dispatch(&mdp, NULL);
|
||||
}
|
||||
|
||||
static int keyring_respond_challenge(struct subscriber *subscriber, overlay_mdp_frame *req)
|
||||
@ -1839,7 +1839,7 @@ static int keyring_respond_challenge(struct subscriber *subscriber, overlay_mdp_
|
||||
if (crypto_sign_message(subscriber, mdp.out.payload, sizeof(mdp.out.payload), &len))
|
||||
return -1;
|
||||
mdp.out.payload_length=len;
|
||||
return overlay_mdp_dispatch(&mdp, 0 /* system generated */, NULL, 0);
|
||||
return overlay_mdp_dispatch(&mdp, NULL);
|
||||
}
|
||||
|
||||
static int keyring_process_challenge(keyring_file *k, struct subscriber *subscriber, overlay_mdp_frame *req)
|
||||
@ -1925,7 +1925,7 @@ int keyring_send_sas_request(struct subscriber *subscriber){
|
||||
mdp.out.payload_length=1;
|
||||
mdp.out.payload[0]=KEYTYPE_CRYPTOSIGN;
|
||||
|
||||
if (overlay_mdp_dispatch(&mdp, 0 /* system generated */, NULL, 0))
|
||||
if (overlay_mdp_dispatch(&mdp, NULL))
|
||||
return WHY("Failed to send SAS resolution request");
|
||||
if (config.debug.keyring)
|
||||
DEBUGF("Dispatched SAS resolution request");
|
||||
|
152
mdp_client.c
152
mdp_client.c
@ -27,6 +27,7 @@
|
||||
#include "overlay_address.h"
|
||||
#include "overlay_packet.h"
|
||||
#include "mdp_client.h"
|
||||
#include "socket.h"
|
||||
|
||||
int mdp_socket(void)
|
||||
{
|
||||
@ -34,49 +35,70 @@ int mdp_socket(void)
|
||||
return overlay_mdp_client_socket();
|
||||
}
|
||||
|
||||
int mdp_close(int socket)
|
||||
static void mdp_unlink(int mdp_sock)
|
||||
{
|
||||
// use the same process for closing sockets, though this will need to change once bind is implemented
|
||||
return overlay_mdp_client_close(socket);
|
||||
// get the socket name and unlink it from the filesystem if not abstract
|
||||
struct socket_address addr;
|
||||
addr.addrlen = sizeof addr.store;
|
||||
if (getsockname(mdp_sock, &addr.addr, &addr.addrlen))
|
||||
WHYF_perror("getsockname(%d)", mdp_sock);
|
||||
else if (addr.addr.sa_family==AF_UNIX
|
||||
&& addr.addrlen > sizeof addr.addr_un.sun_family
|
||||
&& addr.addrlen <= sizeof addr.addr_un && addr.addr_un.sun_path[0] != '\0') {
|
||||
if (unlink(addr.addr_un.sun_path) == -1)
|
||||
WARNF_perror("unlink(%s)", alloca_str_toprint(addr.addr_un.sun_path));
|
||||
}
|
||||
close(mdp_sock);
|
||||
}
|
||||
|
||||
int mdp_send(int socket, const struct mdp_header *header, const unsigned char *payload, ssize_t len)
|
||||
int mdp_close(int socket)
|
||||
{
|
||||
struct sockaddr_un addr;
|
||||
socklen_t addrlen;
|
||||
if (make_local_sockaddr(&addr, &addrlen, "mdp.2.socket") == -1)
|
||||
// tell the daemon to drop all bindings
|
||||
struct mdp_header header={
|
||||
.flags = MDP_FLAG_CLOSE,
|
||||
.local.port = 0,
|
||||
};
|
||||
|
||||
mdp_send(socket, &header, NULL, 0);
|
||||
|
||||
// remove socket
|
||||
mdp_unlink(socket);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mdp_send(int socket, const struct mdp_header *header, const uint8_t *payload, size_t len)
|
||||
{
|
||||
struct socket_address addr;
|
||||
if (make_local_sockaddr(&addr, "mdp.2.socket") == -1)
|
||||
return -1;
|
||||
|
||||
struct iovec iov[]={
|
||||
{
|
||||
.iov_base = (void *)header,
|
||||
.iov_len = sizeof(struct mdp_header)
|
||||
},
|
||||
{
|
||||
.iov_base = (void *)payload,
|
||||
.iov_len = len
|
||||
struct fragmented_data data={
|
||||
.fragment_count=2,
|
||||
.iov={
|
||||
{
|
||||
.iov_base = (void*)header,
|
||||
.iov_len = sizeof(struct mdp_header)
|
||||
},
|
||||
{
|
||||
.iov_base = (void*)payload,
|
||||
.iov_len = len
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct msghdr hdr={
|
||||
.msg_name=&addr,
|
||||
.msg_namelen=addrlen,
|
||||
.msg_iov=iov,
|
||||
.msg_iovlen=2,
|
||||
};
|
||||
|
||||
return sendmsg(socket, &hdr, 0);
|
||||
return send_message(socket, &addr, &data);
|
||||
}
|
||||
|
||||
ssize_t mdp_recv(int socket, struct mdp_header *header, unsigned char *payload, ssize_t max_len)
|
||||
ssize_t mdp_recv(int socket, struct mdp_header *header, uint8_t *payload, ssize_t max_len)
|
||||
{
|
||||
/* Construct name of socket to receive from. */
|
||||
struct sockaddr_un mdp_addr;
|
||||
socklen_t mdp_addrlen;
|
||||
if (make_local_sockaddr(&mdp_addr, &mdp_addrlen, "mdp.2.socket") == -1)
|
||||
return -1;
|
||||
errno=0;
|
||||
struct socket_address mdp_addr;
|
||||
if (make_local_sockaddr(&mdp_addr, "mdp.2.socket") == -1)
|
||||
return WHY("Failed to build socket address");
|
||||
|
||||
struct sockaddr_un addr;
|
||||
struct socket_address addr;
|
||||
struct iovec iov[]={
|
||||
{
|
||||
.iov_base = (void *)header,
|
||||
@ -89,25 +111,26 @@ ssize_t mdp_recv(int socket, struct mdp_header *header, unsigned char *payload,
|
||||
};
|
||||
|
||||
struct msghdr hdr={
|
||||
.msg_name=&addr,
|
||||
.msg_namelen=sizeof(struct sockaddr_un),
|
||||
.msg_name=&addr.addr,
|
||||
.msg_namelen=sizeof(addr.store),
|
||||
.msg_iov=iov,
|
||||
.msg_iovlen=2,
|
||||
};
|
||||
|
||||
ssize_t len = recvmsg(socket, &hdr, 0);
|
||||
if (len<sizeof(struct mdp_header))
|
||||
return -1;
|
||||
|
||||
return WHYF("Received message is too short (%d)", (int)len);
|
||||
addr.addrlen=hdr.msg_namelen;
|
||||
// double check that the incoming address matches the servald daemon
|
||||
if (cmp_sockaddr((struct sockaddr *)&addr, hdr.msg_namelen, (struct sockaddr *)&mdp_addr, mdp_addrlen) != 0
|
||||
&& ( addr.sun_family != AF_UNIX
|
||||
|| real_sockaddr(&addr, hdr.msg_namelen, &addr, &hdr.msg_namelen) <= 0
|
||||
|| cmp_sockaddr((struct sockaddr *)&addr, hdr.msg_namelen, (struct sockaddr *)&mdp_addr, mdp_addrlen) != 0
|
||||
if (cmp_sockaddr(&addr, &mdp_addr) != 0
|
||||
&& ( addr.addr_un.sun_family != AF_UNIX
|
||||
|| real_sockaddr(&addr, &addr) <= 0
|
||||
|| cmp_sockaddr(&addr, &mdp_addr) != 0
|
||||
)
|
||||
)
|
||||
return -1;
|
||||
|
||||
return WHYF("Received message came from %s instead of %s?",
|
||||
alloca_socket_address(&addr),
|
||||
alloca_socket_address(&mdp_addr));
|
||||
return len - sizeof(struct mdp_header);
|
||||
}
|
||||
|
||||
@ -125,19 +148,18 @@ int overlay_mdp_send(int mdp_sockfd, overlay_mdp_frame *mdp, int flags, int time
|
||||
if (len == -1)
|
||||
return WHY("MDP frame invalid (could not compute length)");
|
||||
/* Construct name of socket to send to. */
|
||||
struct sockaddr_un addr;
|
||||
socklen_t addrlen;
|
||||
if (make_local_sockaddr(&addr, &addrlen, "mdp.socket") == -1)
|
||||
struct socket_address addr;
|
||||
if (make_local_sockaddr(&addr, "mdp.socket") == -1)
|
||||
return -1;
|
||||
// Send to that socket
|
||||
set_nonblock(mdp_sockfd);
|
||||
ssize_t result = sendto(mdp_sockfd, mdp, (size_t)len, 0, (struct sockaddr *)&addr, addrlen);
|
||||
ssize_t result = sendto(mdp_sockfd, mdp, (size_t)len, 0, &addr.addr, addr.addrlen);
|
||||
set_block(mdp_sockfd);
|
||||
if ((size_t)result != (size_t)len) {
|
||||
if (result == -1)
|
||||
WHYF_perror("sendto(fd=%d,len=%zu,addr=%s)", mdp_sockfd, (size_t)len, alloca_sockaddr(&addr, addrlen));
|
||||
WHYF_perror("sendto(fd=%d,len=%zu,addr=%s)", mdp_sockfd, (size_t)len, alloca_socket_address(&addr));
|
||||
else
|
||||
WHYF("sendto() sent %zu bytes of MDP reply (%zu) to socket=%d", (size_t)result, (size_t)len, mdp_sockfd);
|
||||
WHYF("sendto() sent %zu bytes of MDP reply (%zu) to %s", (size_t)result, (size_t)len, alloca_socket_address(&addr));
|
||||
mdp->packetTypeAndFlags=MDP_ERROR;
|
||||
mdp->error.error=1;
|
||||
snprintf(mdp->error.message,128,"Error sending frame to MDP server.");
|
||||
@ -181,16 +203,15 @@ int overlay_mdp_client_socket(void)
|
||||
{
|
||||
/* Create local per-client socket to MDP server (connection is always local) */
|
||||
int mdp_sockfd;
|
||||
struct sockaddr_un addr;
|
||||
socklen_t addrlen;
|
||||
struct socket_address addr;
|
||||
uint32_t random_value;
|
||||
if (urandombytes((unsigned char *)&random_value, sizeof random_value) == -1)
|
||||
return WHY("urandombytes() failed");
|
||||
if (make_local_sockaddr(&addr, &addrlen, "mdp.client.%u.%08lx.socket", getpid(), (unsigned long)random_value) == -1)
|
||||
if (make_local_sockaddr(&addr, "mdp.client.%u.%08lx.socket", getpid(), (unsigned long)random_value) == -1)
|
||||
return -1;
|
||||
if ((mdp_sockfd = esocket(AF_UNIX, SOCK_DGRAM, 0)) == -1)
|
||||
return -1;
|
||||
if (socket_bind(mdp_sockfd, (struct sockaddr *)&addr, addrlen) == -1) {
|
||||
if (socket_bind(mdp_sockfd, &addr.addr, addr.addrlen) == -1) {
|
||||
close(mdp_sockfd);
|
||||
return -1;
|
||||
}
|
||||
@ -204,16 +225,8 @@ int overlay_mdp_client_close(int mdp_sockfd)
|
||||
overlay_mdp_frame mdp;
|
||||
mdp.packetTypeAndFlags = MDP_GOODBYE;
|
||||
overlay_mdp_send(mdp_sockfd, &mdp, 0, 0);
|
||||
// get the socket name and unlink it from the filesystem if not abstract
|
||||
struct sockaddr_un addr;
|
||||
socklen_t addrlen = sizeof addr;
|
||||
if (getsockname(mdp_sockfd, (struct sockaddr *)&addr, &addrlen))
|
||||
WHYF_perror("getsockname(%d)", mdp_sockfd);
|
||||
else if (addrlen > sizeof addr.sun_family && addrlen <= sizeof addr && addr.sun_path[0] != '\0') {
|
||||
if (unlink(addr.sun_path) == -1)
|
||||
WARNF_perror("unlink(%s)", alloca_str_toprint(addr.sun_path));
|
||||
}
|
||||
close(mdp_sockfd);
|
||||
|
||||
mdp_unlink(mdp_sockfd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -236,36 +249,35 @@ int overlay_mdp_client_poll(int mdp_sockfd, time_ms_t timeout_ms)
|
||||
int overlay_mdp_recv(int mdp_sockfd, overlay_mdp_frame *mdp, mdp_port_t port, int *ttl)
|
||||
{
|
||||
/* Construct name of socket to receive from. */
|
||||
struct sockaddr_un mdp_addr;
|
||||
socklen_t mdp_addrlen;
|
||||
if (make_local_sockaddr(&mdp_addr, &mdp_addrlen, "mdp.socket") == -1)
|
||||
struct socket_address mdp_addr;
|
||||
if (make_local_sockaddr(&mdp_addr, "mdp.socket") == -1)
|
||||
return -1;
|
||||
|
||||
/* Check if reply available */
|
||||
struct sockaddr_un recvaddr;
|
||||
socklen_t recvaddrlen = sizeof recvaddr;
|
||||
struct socket_address recvaddr;
|
||||
recvaddr.addrlen = sizeof recvaddr.store;
|
||||
ssize_t len;
|
||||
mdp->packetTypeAndFlags = 0;
|
||||
set_nonblock(mdp_sockfd);
|
||||
len = recvwithttl(mdp_sockfd, (unsigned char *)mdp, sizeof(overlay_mdp_frame), ttl, (struct sockaddr *)&recvaddr, &recvaddrlen);
|
||||
len = recvwithttl(mdp_sockfd, (unsigned char *)mdp, sizeof(overlay_mdp_frame), ttl, &recvaddr.addr, &recvaddr.addrlen);
|
||||
set_block(mdp_sockfd);
|
||||
if (len <= 0)
|
||||
return -1; // no packet received
|
||||
|
||||
// If the received address overflowed the buffer, then it cannot have come from the server, whose
|
||||
// address must always fit within a struct sockaddr_un.
|
||||
if (recvaddrlen > sizeof recvaddr)
|
||||
if (recvaddr.addrlen > sizeof recvaddr.store)
|
||||
return WHY("reply did not come from server: address overrun");
|
||||
|
||||
// Compare the address of the sender with the address of our server, to ensure they are the same.
|
||||
// If the comparison fails, then try using realpath(3) on the sender address and compare again.
|
||||
if ( cmp_sockaddr((struct sockaddr *)&recvaddr, recvaddrlen, (struct sockaddr *)&mdp_addr, mdp_addrlen) != 0
|
||||
&& ( recvaddr.sun_family != AF_UNIX
|
||||
|| real_sockaddr(&recvaddr, recvaddrlen, &recvaddr, &recvaddrlen) <= 0
|
||||
|| cmp_sockaddr((struct sockaddr *)&recvaddr, recvaddrlen, (struct sockaddr *)&mdp_addr, mdp_addrlen) != 0
|
||||
if ( cmp_sockaddr(&recvaddr, &mdp_addr) != 0
|
||||
&& ( recvaddr.addr_un.sun_family != AF_UNIX
|
||||
|| real_sockaddr(&recvaddr, &recvaddr) <= 0
|
||||
|| cmp_sockaddr(&recvaddr, &mdp_addr) != 0
|
||||
)
|
||||
)
|
||||
return WHYF("reply did not come from server: %s", alloca_sockaddr(&recvaddr, recvaddrlen));
|
||||
return WHYF("reply did not come from server: %s", alloca_socket_address(&recvaddr));
|
||||
|
||||
// silently drop incoming packets for the wrong port number
|
||||
if (port>0 && port != mdp->in.dst.port){
|
||||
|
17
mdp_client.h
17
mdp_client.h
@ -31,8 +31,9 @@ struct mdp_sockaddr {
|
||||
|
||||
#define MDP_FLAG_NO_CRYPT (1<<0)
|
||||
#define MDP_FLAG_NO_SIGN (1<<1)
|
||||
#define MDP_FLAG_BIND_ALL (1<<2)
|
||||
#define MDP_FLAG_OK (1<<3)
|
||||
#define MDP_FLAG_BIND (1<<2)
|
||||
|
||||
#define MDP_FLAG_CLOSE (1<<3)
|
||||
#define MDP_FLAG_ERROR (1<<4)
|
||||
|
||||
struct mdp_header {
|
||||
@ -43,6 +44,9 @@ struct mdp_header {
|
||||
uint8_t ttl;
|
||||
};
|
||||
|
||||
#define BIND_PRIMARY SID_ANY
|
||||
#define BIND_ALL SID_BROADCAST
|
||||
|
||||
#define TYPE_SID 1
|
||||
#define TYPE_PIN 2
|
||||
#define ACTION_LOCK 1
|
||||
@ -50,6 +54,7 @@ struct mdp_header {
|
||||
|
||||
/* Port numbers for commands sent to the local daemon*/
|
||||
|
||||
#define MDP_LISTEN 0
|
||||
/* lock and unlock identities from the local keyring
|
||||
* Requests start with an mdp_identity_request structure followed by a list of pins or SIDs
|
||||
*/
|
||||
@ -82,13 +87,15 @@ struct overlay_mdp_scan{
|
||||
struct in_addr addr;
|
||||
};
|
||||
|
||||
/* V2 interface */
|
||||
/* low level V2 mdp interface */
|
||||
int mdp_socket(void);
|
||||
int mdp_close(int socket);
|
||||
int mdp_send(int socket, const struct mdp_header *header, const unsigned char *payload, ssize_t len);
|
||||
ssize_t mdp_recv(int socket, struct mdp_header *header, unsigned char *payload, ssize_t max_len);
|
||||
int mdp_send(int socket, const struct mdp_header *header, const uint8_t *payload, size_t len);
|
||||
ssize_t mdp_recv(int socket, struct mdp_header *header, uint8_t *payload, ssize_t max_len);
|
||||
int mdp_poll(int socket, time_ms_t timeout_ms);
|
||||
|
||||
|
||||
|
||||
/* Client-side MDP function */
|
||||
int overlay_mdp_client_socket(void);
|
||||
int overlay_mdp_client_close(int mdp_sockfd);
|
||||
|
@ -36,15 +36,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#endif
|
||||
#include <sys/un.h>
|
||||
#include <fcntl.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "constants.h"
|
||||
#include "conf.h"
|
||||
#include "log.h"
|
||||
#include "str.h"
|
||||
#include "strbuf_helpers.h"
|
||||
|
||||
#include "socket.h"
|
||||
#include "monitor-client.h"
|
||||
#include <ctype.h>
|
||||
|
||||
#define STATE_INIT 0
|
||||
#define STATE_DATA 1
|
||||
@ -72,12 +72,11 @@ int monitor_client_open(struct monitor_state **res)
|
||||
int fd;
|
||||
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
|
||||
return WHYF_perror("socket(AF_UNIX, SOCK_STREAM, 0)");
|
||||
struct sockaddr_un addr;
|
||||
socklen_t addrlen;
|
||||
if (make_local_sockaddr(&addr, &addrlen, "monitor.socket") == -1)
|
||||
struct socket_address addr;
|
||||
if (make_local_sockaddr(&addr, "monitor.socket") == -1)
|
||||
return -1;
|
||||
INFOF("Attempting to connect to %s", alloca_sockaddr(&addr, addrlen));
|
||||
if (socket_connect(fd, (struct sockaddr*)&addr, addrlen) == -1) {
|
||||
INFOF("Attempting to connect to %s", alloca_socket_address(&addr));
|
||||
if (socket_connect(fd, &addr.addr, addr.addrlen) == -1) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
10
monitor.c
10
monitor.c
@ -32,6 +32,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include "strbuf_helpers.h"
|
||||
#include "overlay_address.h"
|
||||
#include "monitor-client.h"
|
||||
#include "socket.h"
|
||||
|
||||
#ifdef HAVE_UCRED_H
|
||||
#include <ucred.h>
|
||||
@ -80,11 +81,10 @@ int monitor_setup_sockets()
|
||||
int sock = -1;
|
||||
if ((sock = esocket(AF_UNIX, SOCK_STREAM, 0)) == -1)
|
||||
goto error;
|
||||
struct sockaddr_un addr;
|
||||
socklen_t addrlen;
|
||||
if (make_local_sockaddr(&addr, &addrlen, "monitor.socket") == -1)
|
||||
struct socket_address addr;
|
||||
if (make_local_sockaddr(&addr, "monitor.socket") == -1)
|
||||
goto error;
|
||||
if (socket_bind(sock, (struct sockaddr*)&addr, addrlen) == -1)
|
||||
if (socket_bind(sock, &addr.addr, addr.addrlen) == -1)
|
||||
goto error;
|
||||
if (socket_listen(sock, MAX_MONITOR_SOCKETS) == -1)
|
||||
goto error;
|
||||
@ -97,7 +97,7 @@ int monitor_setup_sockets()
|
||||
named_socket.poll.fd=sock;
|
||||
named_socket.poll.events=POLLIN;
|
||||
watch(&named_socket);
|
||||
INFOF("Monitor socket: fd=%d %s", sock, alloca_sockaddr(&addr, addrlen));
|
||||
INFOF("Monitor socket: fd=%d %s", sock, alloca_socket_address(&addr));
|
||||
return 0;
|
||||
|
||||
error:
|
||||
|
@ -313,7 +313,7 @@ int overlay_mdp_service_stun_req(overlay_mdp_frame *mdp)
|
||||
if (reply.out.payload_length){
|
||||
if (config.debug.overlayrouting)
|
||||
DEBUGF("Sending reply");
|
||||
overlay_mdp_dispatch(&reply,0 /* system generated */, NULL,0);
|
||||
overlay_mdp_dispatch(&reply, NULL);
|
||||
}
|
||||
ob_free(replypayload);
|
||||
ob_free(payload);
|
||||
@ -387,7 +387,7 @@ int overlay_send_stun_request(struct subscriber *server, struct subscriber *requ
|
||||
mdp.out.payload_length=ob_position(payload);
|
||||
if (config.debug.overlayrouting)
|
||||
DEBUGF("Sending STUN request to %s", alloca_tohex_sid_t(server->sid));
|
||||
overlay_mdp_dispatch(&mdp, 0 /* system generated */, NULL,0);
|
||||
overlay_mdp_dispatch(&mdp, NULL);
|
||||
}
|
||||
ob_free(payload);
|
||||
return 0;
|
||||
|
789
overlay_mdp.c
789
overlay_mdp.c
File diff suppressed because it is too large
Load Diff
@ -99,7 +99,7 @@ int rhizome_mdp_send_block(struct subscriber *dest, const rhizome_bid_t *bid, ui
|
||||
reply.out.payload[0]='T';
|
||||
|
||||
// send packet
|
||||
if (overlay_mdp_dispatch(&reply,0 /* system generated */, NULL,0))
|
||||
if (overlay_mdp_dispatch(&reply, NULL))
|
||||
break;
|
||||
}
|
||||
|
||||
@ -252,8 +252,7 @@ int overlay_mdp_service_echo(overlay_mdp_frame *mdp)
|
||||
mdp->packetTypeAndFlags&=~(MDP_NOCRYPT|MDP_NOSIGN);
|
||||
|
||||
/* queue frame for delivery */
|
||||
overlay_mdp_dispatch(mdp,0 /* system generated */,
|
||||
NULL,0);
|
||||
overlay_mdp_dispatch(mdp, NULL);
|
||||
mdp->packetTypeAndFlags=preserved;
|
||||
|
||||
/* and switch addresses back around in case the caller was planning on
|
||||
@ -342,20 +341,20 @@ static int overlay_mdp_service_trace(overlay_mdp_frame *mdp){
|
||||
mdp->out.payload_length = ob_position(b);
|
||||
mdp->out.src.sid = my_subscriber->sid;
|
||||
mdp->out.dst.sid = next->sid;
|
||||
ret = overlay_mdp_dispatch(mdp, 0, NULL, 0);
|
||||
ret = overlay_mdp_dispatch(mdp, NULL);
|
||||
end:
|
||||
ob_free(b);
|
||||
RETURN(ret);
|
||||
}
|
||||
|
||||
static int overlay_mdp_service_manifest_requests(struct overlay_frame *frame, overlay_mdp_frame *mdp)
|
||||
static int overlay_mdp_service_manifest_requests(struct overlay_frame *frame, const uint8_t *payload, size_t len)
|
||||
{
|
||||
int offset=0;
|
||||
while (offset<mdp->out.payload_length) {
|
||||
while (offset<len) {
|
||||
rhizome_manifest *m = rhizome_new_manifest();
|
||||
if (!m)
|
||||
return WHY("Unable to allocate manifest");
|
||||
unsigned char *bar = &mdp->out.payload[offset];
|
||||
const unsigned char *bar = &payload[offset];
|
||||
if (!rhizome_retrieve_manifest_by_prefix(&bar[RHIZOME_BAR_PREFIX_OFFSET], RHIZOME_BAR_PREFIX_BYTES, m)){
|
||||
rhizome_advertise_manifest(frame->source, m);
|
||||
// pre-emptively send the payload if it will fit in a single packet
|
||||
@ -368,7 +367,7 @@ static int overlay_mdp_service_manifest_requests(struct overlay_frame *frame, ov
|
||||
return 0;
|
||||
}
|
||||
|
||||
int overlay_mdp_try_interal_services(struct overlay_frame *frame, overlay_mdp_frame *mdp)
|
||||
int overlay_mdp_try_internal_services(struct overlay_frame *frame, overlay_mdp_frame *mdp)
|
||||
{
|
||||
IN();
|
||||
switch(mdp->out.dst.port) {
|
||||
@ -383,7 +382,7 @@ int overlay_mdp_try_interal_services(struct overlay_frame *frame, overlay_mdp_fr
|
||||
case MDP_PORT_STUN: RETURN(overlay_mdp_service_stun(mdp));
|
||||
case MDP_PORT_RHIZOME_REQUEST: RETURN(overlay_mdp_service_rhizomerequest(frame, mdp));
|
||||
case MDP_PORT_RHIZOME_RESPONSE: RETURN(overlay_mdp_service_rhizomeresponse(mdp));
|
||||
case MDP_PORT_RHIZOME_MANIFEST_REQUEST: RETURN(overlay_mdp_service_manifest_requests(frame, mdp));
|
||||
case MDP_PORT_RHIZOME_MANIFEST_REQUEST: RETURN(overlay_mdp_service_manifest_requests(frame, mdp->out.payload, mdp->out.payload_length));
|
||||
case MDP_PORT_RHIZOME_SYNC: RETURN(overlay_mdp_service_rhizome_sync(frame, mdp));
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include "str.h"
|
||||
#include "strbuf_helpers.h"
|
||||
#include "overlay_address.h"
|
||||
#include "socket.h"
|
||||
|
||||
/* Represents a queued fetch of a bundle payload, for which the manifest is already known.
|
||||
*/
|
||||
@ -1122,7 +1123,7 @@ static int rhizome_fetch_mdp_requestblocks(struct rhizome_fetch_slot *slot)
|
||||
slot->write_state.file_offset,
|
||||
slot->bidVersion);
|
||||
|
||||
overlay_mdp_dispatch(&mdp,0 /* system generated */,NULL,0);
|
||||
overlay_mdp_dispatch(&mdp, NULL);
|
||||
|
||||
// remember when we sent the request so that we can adjust the inter-request
|
||||
// interval based on how fast the packets arrive.
|
||||
|
@ -482,7 +482,7 @@ next:
|
||||
lookup_time = (end_time - start_time);
|
||||
|
||||
if (mdp.out.payload_length>0)
|
||||
overlay_mdp_dispatch(&mdp,0 /* system generated */,NULL,0);
|
||||
overlay_mdp_dispatch(&mdp, NULL);
|
||||
|
||||
end:
|
||||
sqlite_set_tracefunc(oldfunc);
|
||||
|
@ -93,7 +93,7 @@ static void rhizome_sync_request(struct subscriber *subscriber, uint64_t token,
|
||||
mdp.out.payload_length = ob_position(b);
|
||||
if (config.debug.rhizome)
|
||||
DEBUGF("Sending request to %s for BARs from %"PRIu64" %s", alloca_tohex_sid_t(subscriber->sid), token, forwards?"forwards":"backwards");
|
||||
overlay_mdp_dispatch(&mdp,0,NULL,0);
|
||||
overlay_mdp_dispatch(&mdp, NULL);
|
||||
ob_free(b);
|
||||
}
|
||||
|
||||
@ -147,7 +147,7 @@ static void rhizome_sync_send_requests(struct subscriber *subscriber, struct rhi
|
||||
break;
|
||||
}
|
||||
if (mdp.out.payload_length!=0)
|
||||
overlay_mdp_dispatch(&mdp,0,NULL,0);
|
||||
overlay_mdp_dispatch(&mdp, NULL);
|
||||
|
||||
// send request for more bars if we have room to cache them
|
||||
if (state->bar_count >= CACHE_BARS)
|
||||
@ -440,7 +440,7 @@ static void sync_send_response(struct subscriber *dest, int forwards, uint64_t t
|
||||
mdp.out.payload_length = ob_position(b);
|
||||
if (config.debug.rhizome_ads)
|
||||
DEBUGF("Sending %d BARs from %"PRIu64" to %"PRIu64, count, token, last);
|
||||
overlay_mdp_dispatch(&mdp,0,NULL,0);
|
||||
overlay_mdp_dispatch(&mdp, NULL);
|
||||
}
|
||||
ob_free(b);
|
||||
OUT();
|
||||
|
33
serval.h
33
serval.h
@ -195,28 +195,6 @@ int formf_serval_instance_path(struct __sourceloc, char *buf, size_t bufsiz, con
|
||||
int vformf_serval_instance_path(struct __sourceloc, char *buf, size_t bufsiz, const char *fmt, va_list);
|
||||
void serval_setinstancepath(const char *instancepath);
|
||||
|
||||
/* Basic socket operations.
|
||||
*/
|
||||
int _make_local_sockaddr(struct __sourceloc, struct sockaddr_un *sockname, socklen_t *addrlen, const char *fmt, ...)
|
||||
__attribute__((format(printf, 4, 5)));
|
||||
int _esocket(struct __sourceloc, int domain, int type, int protocol);
|
||||
int _socket_bind(struct __sourceloc, int sock, const struct sockaddr *addr, socklen_t addrlen);
|
||||
int _socket_connect(struct __sourceloc, int sock, const struct sockaddr *addr, socklen_t addrlen);
|
||||
int _socket_listen(struct __sourceloc, int sock, int backlog);
|
||||
int _socket_set_reuseaddr(struct __sourceloc, int sock, int reuseP);
|
||||
int _socket_set_rcvbufsize(struct __sourceloc, int sock, unsigned buffer_size);
|
||||
|
||||
#define make_local_sockaddr(sockname, addrlenp, fmt,...) _make_local_sockaddr(__WHENCE__, (sockname), (addrlenp), (fmt), ##__VA_ARGS__)
|
||||
#define esocket(domain, type, protocol) _esocket(__WHENCE__, (domain), (type), (protocol))
|
||||
#define socket_bind(sock, addr, addrlen) _socket_bind(__WHENCE__, (sock), (addr), (addrlen))
|
||||
#define socket_connect(sock, addr, addrlen) _socket_connect(__WHENCE__, (sock), (addr), (addrlen))
|
||||
#define socket_listen(sock, backlog) _socket_listen(__WHENCE__, (sock), (backlog))
|
||||
#define socket_set_reuseaddr(sock, reuseP) _socket_set_reuseaddr(__WHENCE__, (sock), (reuseP))
|
||||
#define socket_set_rcvbufsize(sock, buffer_size) _socket_set_rcvbufsize(__WHENCE__, (sock), (buffer_size))
|
||||
|
||||
int real_sockaddr(const struct sockaddr_un *src_addr, socklen_t src_addrlen, struct sockaddr_un *dst_addr, socklen_t *dst_addrlen);
|
||||
int cmp_sockaddr(const struct sockaddr *, socklen_t, const struct sockaddr *, socklen_t);
|
||||
|
||||
#define SERVER_CONFIG_RELOAD_INTERVAL_MS 1000
|
||||
|
||||
struct cli_parsed;
|
||||
@ -508,9 +486,6 @@ int rhizome_opendb();
|
||||
int parseCommandLine(struct cli_context *context, const char *argv0, int argc, const char *const *argv);
|
||||
|
||||
int overlay_mdp_get_fds(struct pollfd *fds,int *fdcount,int fdmax);
|
||||
int overlay_mdp_reply_error(int sock,
|
||||
struct sockaddr_un *recvaddr, socklen_t recvaddrlen,
|
||||
int error_number,char *message);
|
||||
|
||||
typedef uint32_t mdp_port_t;
|
||||
#define PRImdp_port_t "#08" PRIx32
|
||||
@ -572,10 +547,8 @@ typedef struct overlay_mdp_frame {
|
||||
|
||||
/* Server-side MDP functions */
|
||||
int overlay_mdp_swap_src_dst(overlay_mdp_frame *mdp);
|
||||
int overlay_mdp_reply(int sock,struct sockaddr_un *recvaddr, socklen_t recvaddrlen,
|
||||
overlay_mdp_frame *mdpreply);
|
||||
int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP,
|
||||
struct sockaddr_un *recvaddr, socklen_t recvaddrlen);
|
||||
struct socket_address;
|
||||
int overlay_mdp_dispatch(overlay_mdp_frame *mdp, struct socket_address *client);
|
||||
void overlay_mdp_encode_ports(struct overlay_buffer *plaintext, mdp_port_t dst_port, mdp_port_t src_port);
|
||||
int overlay_mdp_dnalookup_reply(const sockaddr_mdp *dstaddr, const sid_t *resolved_sidp, const char *uri, const char *did, const char *name);
|
||||
|
||||
@ -688,7 +661,7 @@ int overlay_packetradio_tx_packet(struct overlay_frame *frame);
|
||||
void overlay_dummy_poll(struct sched_ent *alarm);
|
||||
void server_config_reload(struct sched_ent *alarm);
|
||||
void server_shutdown_check(struct sched_ent *alarm);
|
||||
int overlay_mdp_try_interal_services(struct overlay_frame *frame, overlay_mdp_frame *mdp);
|
||||
int overlay_mdp_try_internal_services(struct overlay_frame *frame, overlay_mdp_frame *mdp);
|
||||
int overlay_send_probe(struct subscriber *peer, struct network_destination *destination, int queue);
|
||||
int overlay_send_stun_request(struct subscriber *server, struct subscriber *request);
|
||||
void fd_periodicstats(struct sched_ent *alarm);
|
||||
|
118
socket.c
118
socket.c
@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include "conf.h"
|
||||
#include "log.h"
|
||||
#include "strbuf_helpers.h"
|
||||
#include "socket.h"
|
||||
|
||||
/* Form the name of an AF_UNIX (local) socket in the instance directory as an absolute path.
|
||||
* Under Linux, this will create a socket name in the abstract namespace. This permits us to use
|
||||
@ -40,25 +41,28 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
* @author Daniel O'Connor <daniel@servalproject.com>
|
||||
*/
|
||||
int _make_local_sockaddr(struct __sourceloc __whence, struct sockaddr_un *addr, socklen_t *addrlen, const char *fmt, ...)
|
||||
int _make_local_sockaddr(struct __sourceloc __whence, struct socket_address *addr, const char *fmt, ...)
|
||||
{
|
||||
bzero(addr, sizeof(*addr));
|
||||
addr->addr_un.sun_family = AF_UNIX;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
int r = vformf_serval_instance_path(__WHENCE__, addr->sun_path, sizeof addr->sun_path, fmt, ap);
|
||||
int r = vformf_serval_instance_path(__WHENCE__, addr->addr_un.sun_path, sizeof addr->addr_un.sun_path, fmt, ap);
|
||||
va_end(ap);
|
||||
if (!r)
|
||||
return WHY("socket name overflow");
|
||||
if (real_sockaddr(addr, sizeof addr->sun_family + strlen(addr->sun_path) + 1, addr, addrlen) == -1)
|
||||
return -1;
|
||||
addr->addrlen=sizeof addr->addr_un.sun_family + strlen(addr->addr_un.sun_path) + 1;
|
||||
// TODO perform real path transformation in making the serval instance path
|
||||
// if (real_sockaddr(addr, addr) == -1)
|
||||
// return -1;
|
||||
|
||||
#ifdef USE_ABSTRACT_NAMESPACE
|
||||
// For the abstract name we use the absolute path name with the initial '/' replaced by the
|
||||
// leading nul. This ensures that different instances of the Serval daemon have different socket
|
||||
// names.
|
||||
addr->sun_path[0] = '\0'; // mark as Linux abstract socket
|
||||
--*addrlen; // do not count trailing nul in abstract socket name
|
||||
addr->addr_un.sun_path[0] = '\0'; // mark as Linux abstract socket
|
||||
--addr->addrlen; // do not count trailing nul in abstract socket name
|
||||
#endif // USE_ABSTRACT_NAMESPACE
|
||||
addr->sun_family = AF_UNIX;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -74,31 +78,33 @@ int _make_local_sockaddr(struct __sourceloc __whence, struct sockaddr_un *addr,
|
||||
*
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
*/
|
||||
int real_sockaddr(const struct sockaddr_un *src_addr, socklen_t src_addrlen, struct sockaddr_un *dst_addr, socklen_t *dst_addrlen)
|
||||
int real_sockaddr(const struct socket_address *src_addr, struct socket_address *dst_addr)
|
||||
{
|
||||
int src_path_len = src_addrlen - sizeof src_addr->sun_family;
|
||||
if ( src_addrlen >= sizeof src_addr->sun_family + 1
|
||||
&& src_addr->sun_family == AF_UNIX
|
||||
&& src_addr->sun_path[0] != '\0'
|
||||
&& src_addr->sun_path[src_path_len - 1] == '\0'
|
||||
int src_path_len = src_addr->addrlen - sizeof src_addr->addr_un.sun_family;
|
||||
if ( src_addr->addrlen >= sizeof src_addr->addr_un.sun_family + 1
|
||||
&& src_addr->addr_un.sun_family == AF_UNIX
|
||||
&& src_addr->addr_un.sun_path[0] != '\0'
|
||||
&& src_addr->addr_un.sun_path[src_path_len - 1] == '\0'
|
||||
) {
|
||||
char real_path[PATH_MAX];
|
||||
size_t real_path_len;
|
||||
if (realpath(src_addr->sun_path, real_path) == NULL)
|
||||
return WHYF_perror("realpath(%s)", alloca_str_toprint(src_addr->sun_path));
|
||||
else if ((real_path_len = strlen(real_path) + 1) > sizeof dst_addr->sun_path)
|
||||
return WHYF("sockaddr overrun: realpath(%s) returned %s", alloca_str_toprint(src_addr->sun_path), alloca_str_toprint(real_path));
|
||||
if (realpath(src_addr->addr_un.sun_path, real_path) == NULL)
|
||||
return WHYF_perror("realpath(%s)", alloca_str_toprint(src_addr->addr_un.sun_path));
|
||||
else if ((real_path_len = strlen(real_path) + 1) > sizeof dst_addr->addr_un.sun_path)
|
||||
return WHYF("sockaddr overrun: realpath(%s) returned %s",
|
||||
alloca_str_toprint(src_addr->addr_un.sun_path), alloca_str_toprint(real_path));
|
||||
else if ( real_path_len != src_path_len
|
||||
|| memcmp(real_path, src_addr->sun_path, src_path_len) != 0
|
||||
|| memcmp(real_path, src_addr->addr_un.sun_path, src_path_len) != 0
|
||||
) {
|
||||
memcpy(dst_addr->sun_path, real_path, real_path_len);
|
||||
*dst_addrlen = real_path_len + sizeof dst_addr->sun_family;
|
||||
memcpy(dst_addr->addr_un.sun_path, real_path, real_path_len);
|
||||
dst_addr->addrlen = real_path_len + sizeof dst_addr->addr_un.sun_family;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (dst_addr != src_addr)
|
||||
memcpy(dst_addr, src_addr, src_addrlen);
|
||||
*dst_addrlen = src_addrlen;
|
||||
if (dst_addr != src_addr){
|
||||
memcpy(&dst_addr->addr, &src_addr->addr, src_addr->addrlen);
|
||||
dst_addr->addrlen = src_addr->addrlen;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -107,43 +113,43 @@ int real_sockaddr(const struct sockaddr_un *src_addr, socklen_t src_addrlen, str
|
||||
*
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
*/
|
||||
int cmp_sockaddr(const struct sockaddr *addrA, socklen_t addrlenA, const struct sockaddr *addrB, socklen_t addrlenB)
|
||||
int cmp_sockaddr(const struct socket_address *addrA, const struct socket_address *addrB)
|
||||
{
|
||||
// Two zero-length sockaddrs are equal.
|
||||
if (addrlenA == 0 && addrlenB == 0)
|
||||
if (addrA->addrlen == 0 && addrB->addrlen == 0)
|
||||
return 0;
|
||||
// If either sockaddr is truncated, then we compare the bytes we have.
|
||||
if (addrlenA < sizeof addrA->sa_family || addrlenB < sizeof addrB->sa_family) {
|
||||
int c = memcmp(addrA, addrB, addrlenA < addrlenB ? addrlenA : addrlenB);
|
||||
if (addrA->addrlen < sizeof addrA->addr.sa_family || addrB->addrlen < sizeof addrB->addr.sa_family) {
|
||||
int c = memcmp(addrA, addrB, addrA->addrlen < addrB->addrlen ? addrA->addrlen : addrB->addrlen);
|
||||
if (c == 0)
|
||||
c = addrlenA < addrlenB ? -1 : addrlenA > addrlenB ? 1 : 0;
|
||||
c = addrA->addrlen < addrB->addrlen ? -1 : addrA->addrlen > addrB->addrlen ? 1 : 0;
|
||||
return c;
|
||||
}
|
||||
// Order first by address family.
|
||||
if (addrA->sa_family < addrB->sa_family)
|
||||
if (addrA->addr.sa_family < addrB->addr.sa_family)
|
||||
return -1;
|
||||
if (addrA->sa_family > addrB->sa_family)
|
||||
if (addrA->addr.sa_family > addrB->addr.sa_family)
|
||||
return 1;
|
||||
// Both addresses are in the same family...
|
||||
switch (addrA->sa_family) {
|
||||
switch (addrA->addr.sa_family) {
|
||||
case AF_UNIX: {
|
||||
unsigned pathlenA = addrlenA - sizeof ((const struct sockaddr_un *)addrA)->sun_family;
|
||||
unsigned pathlenB = addrlenB - sizeof ((const struct sockaddr_un *)addrB)->sun_family;
|
||||
unsigned pathlenA = addrA->addrlen - sizeof (addrA->addr_un.sun_family);
|
||||
unsigned pathlenB = addrB->addrlen - sizeof (addrB->addr_un.sun_family);
|
||||
int c;
|
||||
if ( pathlenA > 1 && pathlenB > 1
|
||||
&& ((const struct sockaddr_un *)addrA)->sun_path[0] == '\0'
|
||||
&& ((const struct sockaddr_un *)addrB)->sun_path[0] == '\0'
|
||||
&& addrA->addr_un.sun_path[0] == '\0'
|
||||
&& addrB->addr_un.sun_path[0] == '\0'
|
||||
) {
|
||||
// Both abstract sockets - just compare names, nul bytes are not terminators.
|
||||
c = memcmp(&((const struct sockaddr_un *)addrA)->sun_path[1],
|
||||
&((const struct sockaddr_un *)addrB)->sun_path[1],
|
||||
c = memcmp(&addrA->addr_un.sun_path[1],
|
||||
&addrB->addr_un.sun_path[1],
|
||||
(pathlenA < pathlenB ? pathlenA : pathlenB) - 1);
|
||||
} else {
|
||||
// Either or both are named local file sockets. If the file names are identical up to the
|
||||
// first nul, then the addresses are equal. This collates abstract socket names, whose first
|
||||
// character is a nul, ahead of all non-empty file socket names.
|
||||
c = strncmp(((const struct sockaddr_un *)addrA)->sun_path,
|
||||
((const struct sockaddr_un *)addrB)->sun_path,
|
||||
c = strncmp(addrA->addr_un.sun_path,
|
||||
addrB->addr_un.sun_path,
|
||||
(pathlenA < pathlenB ? pathlenA : pathlenB));
|
||||
}
|
||||
if (c == 0)
|
||||
@ -153,9 +159,10 @@ int cmp_sockaddr(const struct sockaddr *addrA, socklen_t addrlenA, const struct
|
||||
break;
|
||||
}
|
||||
// Fall back to comparing raw data bytes.
|
||||
int c = memcmp(addrA->sa_data, addrB->sa_data, (addrlenA < addrlenB ? addrlenA : addrlenB) - sizeof addrA->sa_family);
|
||||
int c = memcmp(addrA->addr.sa_data, addrB->addr.sa_data,
|
||||
(addrA->addrlen < addrB->addrlen ? addrA->addrlen : addrB->addrlen) - sizeof addrA->addr.sa_family);
|
||||
if (c == 0)
|
||||
c = addrlenA < addrlenB ? -1 : addrlenA > addrlenB ? 1 : 0;
|
||||
c = addrA->addrlen < addrB->addrlen ? -1 : addrA->addrlen > addrB->addrlen ? 1 : 0;
|
||||
return c;
|
||||
}
|
||||
|
||||
@ -225,3 +232,32 @@ int _socket_set_rcvbufsize(struct __sourceloc __whence, int sock, unsigned buffe
|
||||
DEBUGF("setsockopt(%d, SOL_SOCKET, SO_RCVBUF, &%u, %u)", sock, buffer_size, (unsigned)sizeof buffer_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t _send_message(struct __sourceloc __whence, int fd, const struct socket_address *address, const struct fragmented_data *data)
|
||||
{
|
||||
struct msghdr hdr={
|
||||
.msg_name=(void *)&address->addr,
|
||||
.msg_namelen=address->addrlen,
|
||||
.msg_iov=(struct iovec*)data->iov,
|
||||
.msg_iovlen=data->fragment_count,
|
||||
};
|
||||
|
||||
ssize_t ret = sendmsg(fd, &hdr, 0);
|
||||
if (ret==-1)
|
||||
WHYF_perror("sendmsg(%d,%s,%lu)", fd, alloca_socket_address(address), (unsigned long)address->addrlen);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t _recv_message(struct __sourceloc __whence, int fd, struct socket_address *address, struct fragmented_data *data)
|
||||
{
|
||||
struct msghdr hdr={
|
||||
.msg_name=(void *)&address->addr,
|
||||
.msg_namelen=address->addrlen,
|
||||
.msg_iov=data->iov,
|
||||
.msg_iovlen=data->fragment_count,
|
||||
};
|
||||
ssize_t ret = recvmsg(fd, &hdr, 0);
|
||||
if (ret==-1)
|
||||
WHYF_perror("recvmsg(%d,%s,%lu)", fd, alloca_socket_address(address), (unsigned long)address->addrlen);
|
||||
return ret;
|
||||
}
|
||||
|
56
socket.h
Normal file
56
socket.h
Normal file
@ -0,0 +1,56 @@
|
||||
#ifndef __SERVALD_SOCKET_H
|
||||
#define __SERVALD_SOCKET_H
|
||||
|
||||
#ifndef WIN32
|
||||
#include <sys/un.h>
|
||||
#endif
|
||||
|
||||
struct socket_address{
|
||||
socklen_t addrlen;
|
||||
union{
|
||||
struct sockaddr addr;
|
||||
struct sockaddr_un addr_un;
|
||||
struct sockaddr_storage store;
|
||||
};
|
||||
};
|
||||
|
||||
/* Basic socket operations.
|
||||
*/
|
||||
int _make_local_sockaddr(struct __sourceloc, struct socket_address *addr, const char *fmt, ...)
|
||||
__attribute__((format(printf, 3, 4)));
|
||||
int _esocket(struct __sourceloc, int domain, int type, int protocol);
|
||||
int _socket_bind(struct __sourceloc, int sock, const struct sockaddr *addr, socklen_t addrlen);
|
||||
int _socket_connect(struct __sourceloc, int sock, const struct sockaddr *addr, socklen_t addrlen);
|
||||
int _socket_listen(struct __sourceloc, int sock, int backlog);
|
||||
int _socket_set_reuseaddr(struct __sourceloc, int sock, int reuseP);
|
||||
int _socket_set_rcvbufsize(struct __sourceloc, int sock, unsigned buffer_size);
|
||||
|
||||
#define make_local_sockaddr(sockname, fmt,...) _make_local_sockaddr(__WHENCE__, (sockname), (fmt), ##__VA_ARGS__)
|
||||
#define esocket(domain, type, protocol) _esocket(__WHENCE__, (domain), (type), (protocol))
|
||||
#define socket_bind(sock, addr, addrlen) _socket_bind(__WHENCE__, (sock), (addr), (addrlen))
|
||||
#define socket_connect(sock, addr, addrlen) _socket_connect(__WHENCE__, (sock), (addr), (addrlen))
|
||||
#define socket_listen(sock, backlog) _socket_listen(__WHENCE__, (sock), (backlog))
|
||||
#define socket_set_reuseaddr(sock, reuseP) _socket_set_reuseaddr(__WHENCE__, (sock), (reuseP))
|
||||
#define socket_set_rcvbufsize(sock, buffer_size) _socket_set_rcvbufsize(__WHENCE__, (sock), (buffer_size))
|
||||
|
||||
int real_sockaddr(const struct socket_address *src_addr, struct socket_address *dst_addr);
|
||||
int cmp_sockaddr(const struct socket_address *addrA, const struct socket_address *addrB);
|
||||
|
||||
// helper functions for manipulating fragmented packet data
|
||||
#define MAX_FRAGMENTS 8
|
||||
struct fragmented_data{
|
||||
int fragment_count;
|
||||
struct iovec iov[MAX_FRAGMENTS];
|
||||
};
|
||||
|
||||
int prepend_fragment(struct fragmented_data *data, const uint8_t *payload, size_t len);
|
||||
int append_fragment(struct fragmented_data *data, const uint8_t *payload, size_t len);
|
||||
size_t copy_fragment(struct fragmented_data *src, uint8_t *dest, size_t length);
|
||||
|
||||
ssize_t _send_message(struct __sourceloc, int fd, const struct socket_address *address, const struct fragmented_data *data);
|
||||
ssize_t _recv_message(struct __sourceloc, int fd, struct socket_address *address, struct fragmented_data *data);
|
||||
|
||||
#define send_message(fd, address, data) _send_message(__WHENCE__, (fd), (address), (data))
|
||||
#define recv_message(fd, address, data) _recv_message(__WHENCE__, (fd), (address), (data))
|
||||
|
||||
#endif
|
@ -37,6 +37,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include "http_server.h"
|
||||
#include "strbuf_helpers.h"
|
||||
#include "str.h"
|
||||
#include "socket.h"
|
||||
|
||||
static inline strbuf _toprint(strbuf sb, char c)
|
||||
{
|
||||
@ -374,6 +375,11 @@ strbuf strbuf_append_sockaddr(strbuf sb, const struct sockaddr *addr, socklen_t
|
||||
return sb;
|
||||
}
|
||||
|
||||
strbuf strbuf_append_socket_address(strbuf sb, const struct socket_address *addr)
|
||||
{
|
||||
return strbuf_append_sockaddr(sb, &addr->addr, addr->addrlen);
|
||||
}
|
||||
|
||||
strbuf strbuf_append_strftime(strbuf sb, const char *format, const struct tm *tm)
|
||||
{
|
||||
// First, try calling strftime(3) directly on the buffer in the strbuf, if there is one and it
|
||||
|
@ -139,6 +139,10 @@ struct sockaddr;
|
||||
strbuf strbuf_append_sockaddr(strbuf sb, const struct sockaddr *addr, socklen_t addrlen);
|
||||
#define alloca_sockaddr(addr, addrlen) strbuf_str(strbuf_append_sockaddr(strbuf_alloca(200), (const struct sockaddr *)(addr), (addrlen)))
|
||||
|
||||
struct socket_address;
|
||||
strbuf strbuf_append_socket_address(strbuf sb, const struct socket_address *addr);
|
||||
#define alloca_socket_address(addr) strbuf_str(strbuf_append_socket_address(strbuf_alloca(200), (addr)))
|
||||
|
||||
/* Append a strftime(3) string.
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
*/
|
||||
|
4
vomp.c
4
vomp.c
@ -523,7 +523,7 @@ static int vomp_send_status_remote(struct vomp_call_state *call)
|
||||
|
||||
call->local.sequence++;
|
||||
|
||||
overlay_mdp_dispatch(&mdp,0,NULL,0);
|
||||
overlay_mdp_dispatch(&mdp, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -561,7 +561,7 @@ int vomp_received_audio(struct vomp_call_state *call, int audio_codec, int time,
|
||||
|
||||
mdp.out.queue=OQ_ISOCHRONOUS_VOICE;
|
||||
|
||||
overlay_mdp_dispatch(&mdp,0,NULL,0);
|
||||
overlay_mdp_dispatch(&mdp, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user