mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-19 05:07:56 +00:00
Refactor socket name and address length handling
This commit is contained in:
parent
5ea19ab538
commit
0d5d878521
146
commandline.c
146
commandline.c
@ -931,9 +931,6 @@ int app_mdp_ping(const struct cli_parsed *parsed, struct cli_context *context)
|
|||||||
int64_t interval_ms = 1000;
|
int64_t interval_ms = 1000;
|
||||||
str_to_uint64_interval_ms(opt_interval, &interval_ms, NULL);
|
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 */
|
/* First sequence number in the echo frames */
|
||||||
unsigned int firstSeq=random();
|
unsigned int firstSeq=random();
|
||||||
unsigned int sequence_number=firstSeq;
|
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);
|
int broadcast = is_sid_t_broadcast(ping_sid);
|
||||||
|
|
||||||
/* Bind to MDP socket and await confirmation */
|
/* 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");
|
return WHY("Cannot create MDP socket");
|
||||||
|
|
||||||
sid_t srcsid;
|
struct mdp_header mdp_header;
|
||||||
mdp_port_t port=32768+(random()&32767);
|
bzero(&mdp_header, sizeof(mdp_header));
|
||||||
if (overlay_mdp_getmyaddr(mdp_sockfd, 0, &srcsid)) {
|
|
||||||
overlay_mdp_client_close(mdp_sockfd);
|
mdp_header.local.sid = BIND_PRIMARY;
|
||||||
return WHY("Could not get local address");
|
mdp_header.remote.sid = ping_sid;
|
||||||
}
|
mdp_header.remote.port = MDP_PORT_ECHO;
|
||||||
if (overlay_mdp_bind(mdp_sockfd, &srcsid, port)) {
|
mdp_header.qos = OQ_MESH_MANAGEMENT;
|
||||||
overlay_mdp_client_close(mdp_sockfd);
|
mdp_header.ttl = PAYLOAD_TTL_DEFAULT;
|
||||||
return WHY("Could not bind to MDP socket");
|
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 */
|
/* 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_delim(context, "\n");
|
||||||
cli_flush(context);
|
cli_flush(context);
|
||||||
|
|
||||||
@ -968,31 +966,22 @@ int app_mdp_ping(const struct cli_parsed *parsed, struct cli_context *context)
|
|||||||
|
|
||||||
if (broadcast)
|
if (broadcast)
|
||||||
WARN("broadcast ping packets will not be encrypted");
|
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);
|
for (; icount==0 || tx_count<icount; ++sequence_number) {
|
||||||
if (res) {
|
|
||||||
WHYF("could not dispatch PING frame #%d (error %d)%s%s",
|
// send a ping packet
|
||||||
sequence_number - firstSeq,
|
{
|
||||||
res,
|
uint8_t payload[12];
|
||||||
mdp.packetTypeAndFlags == MDP_ERROR ? ": " : "",
|
int *seq=(int *)payload;
|
||||||
mdp.packetTypeAndFlags == MDP_ERROR ? mdp.error.message : ""
|
*seq=sequence_number;
|
||||||
);
|
write_uint64(&payload[4], gettime_ms());
|
||||||
} else
|
|
||||||
|
int r = mdp_send(mdp_sockfd, &mdp_header, payload, sizeof(payload));
|
||||||
|
if (r<0)
|
||||||
|
WHY_perror("mdp_send");
|
||||||
|
else
|
||||||
tx_count++;
|
tx_count++;
|
||||||
|
}
|
||||||
|
|
||||||
/* Now look for replies until one second has passed, and print any replies
|
/* Now look for replies until one second has passed, and print any replies
|
||||||
with appropriate information as required */
|
with appropriate information as required */
|
||||||
@ -1000,29 +989,56 @@ int app_mdp_ping(const struct cli_parsed *parsed, struct cli_context *context)
|
|||||||
time_ms_t finish = now + (tx_count < icount?interval_ms:timeout_ms);
|
time_ms_t finish = now + (tx_count < icount?interval_ms:timeout_ms);
|
||||||
for (; !servalShutdown && now < finish; now = gettime_ms()) {
|
for (; !servalShutdown && now < finish; now = gettime_ms()) {
|
||||||
time_ms_t poll_timeout_ms = finish - 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) {
|
if (mdp_poll(mdp_sockfd, poll_timeout_ms)<=0)
|
||||||
int ttl=-1;
|
continue;
|
||||||
if (overlay_mdp_recv(mdp_sockfd, &mdp, port, &ttl)==0) {
|
|
||||||
switch(mdp.packetTypeAndFlags&MDP_TYPE_MASK) {
|
struct mdp_header mdp_recv_header;
|
||||||
case MDP_ERROR:
|
uint8_t recv_payload[12];
|
||||||
WHYF("mdpping: overlay_mdp_recv: %s (code %d)", mdp.error.message, mdp.error.error);
|
ssize_t len = mdp_recv(mdp_sockfd, &mdp_recv_header, recv_payload, sizeof(recv_payload));
|
||||||
|
|
||||||
|
if (len<0){
|
||||||
|
WHY_perror("mdp_recv");
|
||||||
break;
|
break;
|
||||||
case MDP_TX:
|
}
|
||||||
{
|
|
||||||
int *rxseq=(int *)&mdp.in.payload;
|
if (mdp_recv_header.flags & MDP_FLAG_ERROR){
|
||||||
time_ms_t txtime = read_uint64(&mdp.in.payload[4]);
|
WHY("Serval daemon reported an error, please check the log for more information");
|
||||||
int hop_count = 64 - mdp.in.ttl;
|
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;
|
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),
|
cli_put_hexvalue(context, mdp_recv_header.remote.sid.binary, SID_SIZE, ": seq=");
|
||||||
(*rxseq)-firstSeq+1,
|
cli_put_long(context, (*rxseq)-firstSeq+1, " time=");
|
||||||
(int64_t)delay,
|
cli_put_long(context, delay, "ms hops=");
|
||||||
hop_count,
|
cli_put_long(context, hop_count, "");
|
||||||
mdp.packetTypeAndFlags&MDP_NOCRYPT?"":" ENCRYPTED",
|
|
||||||
mdp.packetTypeAndFlags&MDP_NOSIGN?"":" SIGNED");
|
if (mdp_recv_header.flags&MDP_FLAG_NO_CRYPT)
|
||||||
cli_delim(context, "\n");
|
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);
|
cli_flush(context);
|
||||||
// TODO Put duplicate pong detection here so that stats work properly.
|
// TODO Put duplicate pong detection here so that stats work properly.
|
||||||
rx_count++;
|
rx_count++;
|
||||||
@ -1032,17 +1048,9 @@ int app_mdp_ping(const struct cli_parsed *parsed, struct cli_context *context)
|
|||||||
if (delay>rx_maxtime) rx_maxtime=delay;
|
if (delay>rx_maxtime) rx_maxtime=delay;
|
||||||
rx_times[rx_count%1024]=delay;
|
rx_times[rx_count%1024]=delay;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
default:
|
|
||||||
WHYF("mdpping: overlay_mdp_recv: Unexpected MDP frame type 0x%x", mdp.packetTypeAndFlags);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
overlay_mdp_client_close(mdp_sockfd);
|
mdp_close(mdp_sockfd);
|
||||||
|
|
||||||
{
|
{
|
||||||
float rx_stddev=0;
|
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");
|
WHYF("Timeout while waiting for response");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (rev_header.flags & MDP_FLAG_OK){
|
if (rev_header.flags & MDP_FLAG_CLOSE){
|
||||||
ret=0;
|
ret=0;
|
||||||
break;
|
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
|
// 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;
|
ret=0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ static void directory_send(struct subscriber *directory_service, const sid_t *si
|
|||||||
// Used by tests
|
// Used by tests
|
||||||
INFOF("Sending directory registration for %s*, %s, %s to %s*",
|
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));
|
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
|
// send a registration packet for each unlocked identity
|
||||||
|
@ -6,6 +6,7 @@ HDRS= fifo.h \
|
|||||||
rhizome.h \
|
rhizome.h \
|
||||||
serval.h \
|
serval.h \
|
||||||
keyring.h \
|
keyring.h \
|
||||||
|
socket.h \
|
||||||
cli.h \
|
cli.h \
|
||||||
str.h \
|
str.h \
|
||||||
rotbuf.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.src.sid), req->out.src.port,
|
||||||
alloca_tohex_sid_t(req->out.dst.sid), req->out.dst.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
|
// 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))
|
if (crypto_sign_message(subscriber, mdp.out.payload, sizeof(mdp.out.payload), &len))
|
||||||
return -1;
|
return -1;
|
||||||
mdp.out.payload_length=len;
|
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)
|
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));
|
bcopy(source->identity->challenge, &mdp.out.payload[1], sizeof(source->identity->challenge));
|
||||||
mdp.out.payload_length+=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)
|
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))
|
if (crypto_sign_message(subscriber, mdp.out.payload, sizeof(mdp.out.payload), &len))
|
||||||
return -1;
|
return -1;
|
||||||
mdp.out.payload_length=len;
|
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)
|
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_length=1;
|
||||||
mdp.out.payload[0]=KEYTYPE_CRYPTOSIGN;
|
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");
|
return WHY("Failed to send SAS resolution request");
|
||||||
if (config.debug.keyring)
|
if (config.debug.keyring)
|
||||||
DEBUGF("Dispatched SAS resolution request");
|
DEBUGF("Dispatched SAS resolution request");
|
||||||
|
138
mdp_client.c
138
mdp_client.c
@ -27,6 +27,7 @@
|
|||||||
#include "overlay_address.h"
|
#include "overlay_address.h"
|
||||||
#include "overlay_packet.h"
|
#include "overlay_packet.h"
|
||||||
#include "mdp_client.h"
|
#include "mdp_client.h"
|
||||||
|
#include "socket.h"
|
||||||
|
|
||||||
int mdp_socket(void)
|
int mdp_socket(void)
|
||||||
{
|
{
|
||||||
@ -34,20 +35,46 @@ int mdp_socket(void)
|
|||||||
return overlay_mdp_client_socket();
|
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
|
// get the socket name and unlink it from the filesystem if not abstract
|
||||||
return overlay_mdp_client_close(socket);
|
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;
|
// tell the daemon to drop all bindings
|
||||||
socklen_t addrlen;
|
struct mdp_header header={
|
||||||
if (make_local_sockaddr(&addr, &addrlen, "mdp.2.socket") == -1)
|
.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;
|
return -1;
|
||||||
|
|
||||||
struct iovec iov[]={
|
struct fragmented_data data={
|
||||||
|
.fragment_count=2,
|
||||||
|
.iov={
|
||||||
{
|
{
|
||||||
.iov_base = (void*)header,
|
.iov_base = (void*)header,
|
||||||
.iov_len = sizeof(struct mdp_header)
|
.iov_len = sizeof(struct mdp_header)
|
||||||
@ -56,27 +83,22 @@ int mdp_send(int socket, const struct mdp_header *header, const unsigned char *p
|
|||||||
.iov_base = (void*)payload,
|
.iov_base = (void*)payload,
|
||||||
.iov_len = len
|
.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. */
|
/* Construct name of socket to receive from. */
|
||||||
struct sockaddr_un mdp_addr;
|
errno=0;
|
||||||
socklen_t mdp_addrlen;
|
struct socket_address mdp_addr;
|
||||||
if (make_local_sockaddr(&mdp_addr, &mdp_addrlen, "mdp.2.socket") == -1)
|
if (make_local_sockaddr(&mdp_addr, "mdp.2.socket") == -1)
|
||||||
return -1;
|
return WHY("Failed to build socket address");
|
||||||
|
|
||||||
struct sockaddr_un addr;
|
struct socket_address addr;
|
||||||
struct iovec iov[]={
|
struct iovec iov[]={
|
||||||
{
|
{
|
||||||
.iov_base = (void *)header,
|
.iov_base = (void *)header,
|
||||||
@ -89,25 +111,26 @@ ssize_t mdp_recv(int socket, struct mdp_header *header, unsigned char *payload,
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct msghdr hdr={
|
struct msghdr hdr={
|
||||||
.msg_name=&addr,
|
.msg_name=&addr.addr,
|
||||||
.msg_namelen=sizeof(struct sockaddr_un),
|
.msg_namelen=sizeof(addr.store),
|
||||||
.msg_iov=iov,
|
.msg_iov=iov,
|
||||||
.msg_iovlen=2,
|
.msg_iovlen=2,
|
||||||
};
|
};
|
||||||
|
|
||||||
ssize_t len = recvmsg(socket, &hdr, 0);
|
ssize_t len = recvmsg(socket, &hdr, 0);
|
||||||
if (len<sizeof(struct mdp_header))
|
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
|
// 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
|
if (cmp_sockaddr(&addr, &mdp_addr) != 0
|
||||||
&& ( addr.sun_family != AF_UNIX
|
&& ( addr.addr_un.sun_family != AF_UNIX
|
||||||
|| real_sockaddr(&addr, hdr.msg_namelen, &addr, &hdr.msg_namelen) <= 0
|
|| real_sockaddr(&addr, &addr) <= 0
|
||||||
|| cmp_sockaddr((struct sockaddr *)&addr, hdr.msg_namelen, (struct sockaddr *)&mdp_addr, mdp_addrlen) != 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);
|
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)
|
if (len == -1)
|
||||||
return WHY("MDP frame invalid (could not compute length)");
|
return WHY("MDP frame invalid (could not compute length)");
|
||||||
/* Construct name of socket to send to. */
|
/* Construct name of socket to send to. */
|
||||||
struct sockaddr_un addr;
|
struct socket_address addr;
|
||||||
socklen_t addrlen;
|
if (make_local_sockaddr(&addr, "mdp.socket") == -1)
|
||||||
if (make_local_sockaddr(&addr, &addrlen, "mdp.socket") == -1)
|
|
||||||
return -1;
|
return -1;
|
||||||
// Send to that socket
|
// Send to that socket
|
||||||
set_nonblock(mdp_sockfd);
|
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);
|
set_block(mdp_sockfd);
|
||||||
if ((size_t)result != (size_t)len) {
|
if ((size_t)result != (size_t)len) {
|
||||||
if (result == -1)
|
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
|
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->packetTypeAndFlags=MDP_ERROR;
|
||||||
mdp->error.error=1;
|
mdp->error.error=1;
|
||||||
snprintf(mdp->error.message,128,"Error sending frame to MDP server.");
|
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) */
|
/* Create local per-client socket to MDP server (connection is always local) */
|
||||||
int mdp_sockfd;
|
int mdp_sockfd;
|
||||||
struct sockaddr_un addr;
|
struct socket_address addr;
|
||||||
socklen_t addrlen;
|
|
||||||
uint32_t random_value;
|
uint32_t random_value;
|
||||||
if (urandombytes((unsigned char *)&random_value, sizeof random_value) == -1)
|
if (urandombytes((unsigned char *)&random_value, sizeof random_value) == -1)
|
||||||
return WHY("urandombytes() failed");
|
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;
|
return -1;
|
||||||
if ((mdp_sockfd = esocket(AF_UNIX, SOCK_DGRAM, 0)) == -1)
|
if ((mdp_sockfd = esocket(AF_UNIX, SOCK_DGRAM, 0)) == -1)
|
||||||
return -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);
|
close(mdp_sockfd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -204,16 +225,8 @@ int overlay_mdp_client_close(int mdp_sockfd)
|
|||||||
overlay_mdp_frame mdp;
|
overlay_mdp_frame mdp;
|
||||||
mdp.packetTypeAndFlags = MDP_GOODBYE;
|
mdp.packetTypeAndFlags = MDP_GOODBYE;
|
||||||
overlay_mdp_send(mdp_sockfd, &mdp, 0, 0);
|
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;
|
mdp_unlink(mdp_sockfd);
|
||||||
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);
|
|
||||||
return 0;
|
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)
|
int overlay_mdp_recv(int mdp_sockfd, overlay_mdp_frame *mdp, mdp_port_t port, int *ttl)
|
||||||
{
|
{
|
||||||
/* Construct name of socket to receive from. */
|
/* Construct name of socket to receive from. */
|
||||||
struct sockaddr_un mdp_addr;
|
struct socket_address mdp_addr;
|
||||||
socklen_t mdp_addrlen;
|
if (make_local_sockaddr(&mdp_addr, "mdp.socket") == -1)
|
||||||
if (make_local_sockaddr(&mdp_addr, &mdp_addrlen, "mdp.socket") == -1)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Check if reply available */
|
/* Check if reply available */
|
||||||
struct sockaddr_un recvaddr;
|
struct socket_address recvaddr;
|
||||||
socklen_t recvaddrlen = sizeof recvaddr;
|
recvaddr.addrlen = sizeof recvaddr.store;
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
mdp->packetTypeAndFlags = 0;
|
mdp->packetTypeAndFlags = 0;
|
||||||
set_nonblock(mdp_sockfd);
|
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);
|
set_block(mdp_sockfd);
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
return -1; // no packet received
|
return -1; // no packet received
|
||||||
|
|
||||||
// If the received address overflowed the buffer, then it cannot have come from the server, whose
|
// 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.
|
// 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");
|
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.
|
// 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 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
|
if ( cmp_sockaddr(&recvaddr, &mdp_addr) != 0
|
||||||
&& ( recvaddr.sun_family != AF_UNIX
|
&& ( recvaddr.addr_un.sun_family != AF_UNIX
|
||||||
|| real_sockaddr(&recvaddr, recvaddrlen, &recvaddr, &recvaddrlen) <= 0
|
|| real_sockaddr(&recvaddr, &recvaddr) <= 0
|
||||||
|| cmp_sockaddr((struct sockaddr *)&recvaddr, recvaddrlen, (struct sockaddr *)&mdp_addr, mdp_addrlen) != 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
|
// silently drop incoming packets for the wrong port number
|
||||||
if (port>0 && port != mdp->in.dst.port){
|
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_CRYPT (1<<0)
|
||||||
#define MDP_FLAG_NO_SIGN (1<<1)
|
#define MDP_FLAG_NO_SIGN (1<<1)
|
||||||
#define MDP_FLAG_BIND_ALL (1<<2)
|
#define MDP_FLAG_BIND (1<<2)
|
||||||
#define MDP_FLAG_OK (1<<3)
|
|
||||||
|
#define MDP_FLAG_CLOSE (1<<3)
|
||||||
#define MDP_FLAG_ERROR (1<<4)
|
#define MDP_FLAG_ERROR (1<<4)
|
||||||
|
|
||||||
struct mdp_header {
|
struct mdp_header {
|
||||||
@ -43,6 +44,9 @@ struct mdp_header {
|
|||||||
uint8_t ttl;
|
uint8_t ttl;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define BIND_PRIMARY SID_ANY
|
||||||
|
#define BIND_ALL SID_BROADCAST
|
||||||
|
|
||||||
#define TYPE_SID 1
|
#define TYPE_SID 1
|
||||||
#define TYPE_PIN 2
|
#define TYPE_PIN 2
|
||||||
#define ACTION_LOCK 1
|
#define ACTION_LOCK 1
|
||||||
@ -50,6 +54,7 @@ struct mdp_header {
|
|||||||
|
|
||||||
/* Port numbers for commands sent to the local daemon*/
|
/* Port numbers for commands sent to the local daemon*/
|
||||||
|
|
||||||
|
#define MDP_LISTEN 0
|
||||||
/* lock and unlock identities from the local keyring
|
/* lock and unlock identities from the local keyring
|
||||||
* Requests start with an mdp_identity_request structure followed by a list of pins or SIDs
|
* 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;
|
struct in_addr addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* V2 interface */
|
/* low level V2 mdp interface */
|
||||||
int mdp_socket(void);
|
int mdp_socket(void);
|
||||||
int mdp_close(int socket);
|
int mdp_close(int socket);
|
||||||
int mdp_send(int socket, const struct mdp_header *header, const unsigned char *payload, ssize_t 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, unsigned char *payload, ssize_t max_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);
|
int mdp_poll(int socket, time_ms_t timeout_ms);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Client-side MDP function */
|
/* Client-side MDP function */
|
||||||
int overlay_mdp_client_socket(void);
|
int overlay_mdp_client_socket(void);
|
||||||
int overlay_mdp_client_close(int mdp_sockfd);
|
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
|
#endif
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "str.h"
|
#include "str.h"
|
||||||
#include "strbuf_helpers.h"
|
#include "strbuf_helpers.h"
|
||||||
|
#include "socket.h"
|
||||||
#include "monitor-client.h"
|
#include "monitor-client.h"
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#define STATE_INIT 0
|
#define STATE_INIT 0
|
||||||
#define STATE_DATA 1
|
#define STATE_DATA 1
|
||||||
@ -72,12 +72,11 @@ int monitor_client_open(struct monitor_state **res)
|
|||||||
int fd;
|
int fd;
|
||||||
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
|
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
|
||||||
return WHYF_perror("socket(AF_UNIX, SOCK_STREAM, 0)");
|
return WHYF_perror("socket(AF_UNIX, SOCK_STREAM, 0)");
|
||||||
struct sockaddr_un addr;
|
struct socket_address addr;
|
||||||
socklen_t addrlen;
|
if (make_local_sockaddr(&addr, "monitor.socket") == -1)
|
||||||
if (make_local_sockaddr(&addr, &addrlen, "monitor.socket") == -1)
|
|
||||||
return -1;
|
return -1;
|
||||||
INFOF("Attempting to connect to %s", alloca_sockaddr(&addr, addrlen));
|
INFOF("Attempting to connect to %s", alloca_socket_address(&addr));
|
||||||
if (socket_connect(fd, (struct sockaddr*)&addr, addrlen) == -1) {
|
if (socket_connect(fd, &addr.addr, addr.addrlen) == -1) {
|
||||||
close(fd);
|
close(fd);
|
||||||
return -1;
|
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 "strbuf_helpers.h"
|
||||||
#include "overlay_address.h"
|
#include "overlay_address.h"
|
||||||
#include "monitor-client.h"
|
#include "monitor-client.h"
|
||||||
|
#include "socket.h"
|
||||||
|
|
||||||
#ifdef HAVE_UCRED_H
|
#ifdef HAVE_UCRED_H
|
||||||
#include <ucred.h>
|
#include <ucred.h>
|
||||||
@ -80,11 +81,10 @@ int monitor_setup_sockets()
|
|||||||
int sock = -1;
|
int sock = -1;
|
||||||
if ((sock = esocket(AF_UNIX, SOCK_STREAM, 0)) == -1)
|
if ((sock = esocket(AF_UNIX, SOCK_STREAM, 0)) == -1)
|
||||||
goto error;
|
goto error;
|
||||||
struct sockaddr_un addr;
|
struct socket_address addr;
|
||||||
socklen_t addrlen;
|
if (make_local_sockaddr(&addr, "monitor.socket") == -1)
|
||||||
if (make_local_sockaddr(&addr, &addrlen, "monitor.socket") == -1)
|
|
||||||
goto error;
|
goto error;
|
||||||
if (socket_bind(sock, (struct sockaddr*)&addr, addrlen) == -1)
|
if (socket_bind(sock, &addr.addr, addr.addrlen) == -1)
|
||||||
goto error;
|
goto error;
|
||||||
if (socket_listen(sock, MAX_MONITOR_SOCKETS) == -1)
|
if (socket_listen(sock, MAX_MONITOR_SOCKETS) == -1)
|
||||||
goto error;
|
goto error;
|
||||||
@ -97,7 +97,7 @@ int monitor_setup_sockets()
|
|||||||
named_socket.poll.fd=sock;
|
named_socket.poll.fd=sock;
|
||||||
named_socket.poll.events=POLLIN;
|
named_socket.poll.events=POLLIN;
|
||||||
watch(&named_socket);
|
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;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -313,7 +313,7 @@ int overlay_mdp_service_stun_req(overlay_mdp_frame *mdp)
|
|||||||
if (reply.out.payload_length){
|
if (reply.out.payload_length){
|
||||||
if (config.debug.overlayrouting)
|
if (config.debug.overlayrouting)
|
||||||
DEBUGF("Sending reply");
|
DEBUGF("Sending reply");
|
||||||
overlay_mdp_dispatch(&reply,0 /* system generated */, NULL,0);
|
overlay_mdp_dispatch(&reply, NULL);
|
||||||
}
|
}
|
||||||
ob_free(replypayload);
|
ob_free(replypayload);
|
||||||
ob_free(payload);
|
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);
|
mdp.out.payload_length=ob_position(payload);
|
||||||
if (config.debug.overlayrouting)
|
if (config.debug.overlayrouting)
|
||||||
DEBUGF("Sending STUN request to %s", alloca_tohex_sid_t(server->sid));
|
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);
|
ob_free(payload);
|
||||||
return 0;
|
return 0;
|
||||||
|
667
overlay_mdp.c
667
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';
|
reply.out.payload[0]='T';
|
||||||
|
|
||||||
// send packet
|
// send packet
|
||||||
if (overlay_mdp_dispatch(&reply,0 /* system generated */, NULL,0))
|
if (overlay_mdp_dispatch(&reply, NULL))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,8 +252,7 @@ int overlay_mdp_service_echo(overlay_mdp_frame *mdp)
|
|||||||
mdp->packetTypeAndFlags&=~(MDP_NOCRYPT|MDP_NOSIGN);
|
mdp->packetTypeAndFlags&=~(MDP_NOCRYPT|MDP_NOSIGN);
|
||||||
|
|
||||||
/* queue frame for delivery */
|
/* queue frame for delivery */
|
||||||
overlay_mdp_dispatch(mdp,0 /* system generated */,
|
overlay_mdp_dispatch(mdp, NULL);
|
||||||
NULL,0);
|
|
||||||
mdp->packetTypeAndFlags=preserved;
|
mdp->packetTypeAndFlags=preserved;
|
||||||
|
|
||||||
/* and switch addresses back around in case the caller was planning on
|
/* 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.payload_length = ob_position(b);
|
||||||
mdp->out.src.sid = my_subscriber->sid;
|
mdp->out.src.sid = my_subscriber->sid;
|
||||||
mdp->out.dst.sid = next->sid;
|
mdp->out.dst.sid = next->sid;
|
||||||
ret = overlay_mdp_dispatch(mdp, 0, NULL, 0);
|
ret = overlay_mdp_dispatch(mdp, NULL);
|
||||||
end:
|
end:
|
||||||
ob_free(b);
|
ob_free(b);
|
||||||
RETURN(ret);
|
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;
|
int offset=0;
|
||||||
while (offset<mdp->out.payload_length) {
|
while (offset<len) {
|
||||||
rhizome_manifest *m = rhizome_new_manifest();
|
rhizome_manifest *m = rhizome_new_manifest();
|
||||||
if (!m)
|
if (!m)
|
||||||
return WHY("Unable to allocate manifest");
|
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)){
|
if (!rhizome_retrieve_manifest_by_prefix(&bar[RHIZOME_BAR_PREFIX_OFFSET], RHIZOME_BAR_PREFIX_BYTES, m)){
|
||||||
rhizome_advertise_manifest(frame->source, m);
|
rhizome_advertise_manifest(frame->source, m);
|
||||||
// pre-emptively send the payload if it will fit in a single packet
|
// 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;
|
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();
|
IN();
|
||||||
switch(mdp->out.dst.port) {
|
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_STUN: RETURN(overlay_mdp_service_stun(mdp));
|
||||||
case MDP_PORT_RHIZOME_REQUEST: RETURN(overlay_mdp_service_rhizomerequest(frame, 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_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));
|
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 "str.h"
|
||||||
#include "strbuf_helpers.h"
|
#include "strbuf_helpers.h"
|
||||||
#include "overlay_address.h"
|
#include "overlay_address.h"
|
||||||
|
#include "socket.h"
|
||||||
|
|
||||||
/* Represents a queued fetch of a bundle payload, for which the manifest is already known.
|
/* 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->write_state.file_offset,
|
||||||
slot->bidVersion);
|
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
|
// remember when we sent the request so that we can adjust the inter-request
|
||||||
// interval based on how fast the packets arrive.
|
// interval based on how fast the packets arrive.
|
||||||
|
@ -482,7 +482,7 @@ next:
|
|||||||
lookup_time = (end_time - start_time);
|
lookup_time = (end_time - start_time);
|
||||||
|
|
||||||
if (mdp.out.payload_length>0)
|
if (mdp.out.payload_length>0)
|
||||||
overlay_mdp_dispatch(&mdp,0 /* system generated */,NULL,0);
|
overlay_mdp_dispatch(&mdp, NULL);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
sqlite_set_tracefunc(oldfunc);
|
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);
|
mdp.out.payload_length = ob_position(b);
|
||||||
if (config.debug.rhizome)
|
if (config.debug.rhizome)
|
||||||
DEBUGF("Sending request to %s for BARs from %"PRIu64" %s", alloca_tohex_sid_t(subscriber->sid), token, forwards?"forwards":"backwards");
|
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);
|
ob_free(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,7 +147,7 @@ static void rhizome_sync_send_requests(struct subscriber *subscriber, struct rhi
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (mdp.out.payload_length!=0)
|
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
|
// send request for more bars if we have room to cache them
|
||||||
if (state->bar_count >= CACHE_BARS)
|
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);
|
mdp.out.payload_length = ob_position(b);
|
||||||
if (config.debug.rhizome_ads)
|
if (config.debug.rhizome_ads)
|
||||||
DEBUGF("Sending %d BARs from %"PRIu64" to %"PRIu64, count, token, last);
|
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);
|
ob_free(b);
|
||||||
OUT();
|
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);
|
int vformf_serval_instance_path(struct __sourceloc, char *buf, size_t bufsiz, const char *fmt, va_list);
|
||||||
void serval_setinstancepath(const char *instancepath);
|
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
|
#define SERVER_CONFIG_RELOAD_INTERVAL_MS 1000
|
||||||
|
|
||||||
struct cli_parsed;
|
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 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_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;
|
typedef uint32_t mdp_port_t;
|
||||||
#define PRImdp_port_t "#08" PRIx32
|
#define PRImdp_port_t "#08" PRIx32
|
||||||
@ -572,10 +547,8 @@ typedef struct overlay_mdp_frame {
|
|||||||
|
|
||||||
/* Server-side MDP functions */
|
/* Server-side MDP functions */
|
||||||
int overlay_mdp_swap_src_dst(overlay_mdp_frame *mdp);
|
int overlay_mdp_swap_src_dst(overlay_mdp_frame *mdp);
|
||||||
int overlay_mdp_reply(int sock,struct sockaddr_un *recvaddr, socklen_t recvaddrlen,
|
struct socket_address;
|
||||||
overlay_mdp_frame *mdpreply);
|
int overlay_mdp_dispatch(overlay_mdp_frame *mdp, struct socket_address *client);
|
||||||
int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP,
|
|
||||||
struct sockaddr_un *recvaddr, socklen_t recvaddrlen);
|
|
||||||
void overlay_mdp_encode_ports(struct overlay_buffer *plaintext, mdp_port_t dst_port, mdp_port_t src_port);
|
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);
|
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 overlay_dummy_poll(struct sched_ent *alarm);
|
||||||
void server_config_reload(struct sched_ent *alarm);
|
void server_config_reload(struct sched_ent *alarm);
|
||||||
void server_shutdown_check(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_probe(struct subscriber *peer, struct network_destination *destination, int queue);
|
||||||
int overlay_send_stun_request(struct subscriber *server, struct subscriber *request);
|
int overlay_send_stun_request(struct subscriber *server, struct subscriber *request);
|
||||||
void fd_periodicstats(struct sched_ent *alarm);
|
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 "conf.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "strbuf_helpers.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.
|
/* 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
|
* 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 Andrew Bettison <andrew@servalproject.com>
|
||||||
* @author Daniel O'Connor <daniel@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));
|
bzero(addr, sizeof(*addr));
|
||||||
|
addr->addr_un.sun_family = AF_UNIX;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
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);
|
va_end(ap);
|
||||||
if (!r)
|
if (!r)
|
||||||
return WHY("socket name overflow");
|
return WHY("socket name overflow");
|
||||||
if (real_sockaddr(addr, sizeof addr->sun_family + strlen(addr->sun_path) + 1, addr, addrlen) == -1)
|
addr->addrlen=sizeof addr->addr_un.sun_family + strlen(addr->addr_un.sun_path) + 1;
|
||||||
return -1;
|
// TODO perform real path transformation in making the serval instance path
|
||||||
|
// if (real_sockaddr(addr, addr) == -1)
|
||||||
|
// return -1;
|
||||||
|
|
||||||
#ifdef USE_ABSTRACT_NAMESPACE
|
#ifdef USE_ABSTRACT_NAMESPACE
|
||||||
// For the abstract name we use the absolute path name with the initial '/' replaced by the
|
// 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
|
// leading nul. This ensures that different instances of the Serval daemon have different socket
|
||||||
// names.
|
// names.
|
||||||
addr->sun_path[0] = '\0'; // mark as Linux abstract socket
|
addr->addr_un.sun_path[0] = '\0'; // mark as Linux abstract socket
|
||||||
--*addrlen; // do not count trailing nul in abstract socket name
|
--addr->addrlen; // do not count trailing nul in abstract socket name
|
||||||
#endif // USE_ABSTRACT_NAMESPACE
|
#endif // USE_ABSTRACT_NAMESPACE
|
||||||
addr->sun_family = AF_UNIX;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,31 +78,33 @@ int _make_local_sockaddr(struct __sourceloc __whence, struct sockaddr_un *addr,
|
|||||||
*
|
*
|
||||||
* @author Andrew Bettison <andrew@servalproject.com>
|
* @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;
|
int src_path_len = src_addr->addrlen - sizeof src_addr->addr_un.sun_family;
|
||||||
if ( src_addrlen >= sizeof src_addr->sun_family + 1
|
if ( src_addr->addrlen >= sizeof src_addr->addr_un.sun_family + 1
|
||||||
&& src_addr->sun_family == AF_UNIX
|
&& src_addr->addr_un.sun_family == AF_UNIX
|
||||||
&& src_addr->sun_path[0] != '\0'
|
&& src_addr->addr_un.sun_path[0] != '\0'
|
||||||
&& src_addr->sun_path[src_path_len - 1] == '\0'
|
&& src_addr->addr_un.sun_path[src_path_len - 1] == '\0'
|
||||||
) {
|
) {
|
||||||
char real_path[PATH_MAX];
|
char real_path[PATH_MAX];
|
||||||
size_t real_path_len;
|
size_t real_path_len;
|
||||||
if (realpath(src_addr->sun_path, real_path) == NULL)
|
if (realpath(src_addr->addr_un.sun_path, real_path) == NULL)
|
||||||
return WHYF_perror("realpath(%s)", alloca_str_toprint(src_addr->sun_path));
|
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->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->sun_path), alloca_str_toprint(real_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
|
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);
|
memcpy(dst_addr->addr_un.sun_path, real_path, real_path_len);
|
||||||
*dst_addrlen = real_path_len + sizeof dst_addr->sun_family;
|
dst_addr->addrlen = real_path_len + sizeof dst_addr->addr_un.sun_family;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dst_addr != src_addr)
|
if (dst_addr != src_addr){
|
||||||
memcpy(dst_addr, src_addr, src_addrlen);
|
memcpy(&dst_addr->addr, &src_addr->addr, src_addr->addrlen);
|
||||||
*dst_addrlen = src_addrlen;
|
dst_addr->addrlen = src_addr->addrlen;
|
||||||
|
}
|
||||||
return 0;
|
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>
|
* @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.
|
// Two zero-length sockaddrs are equal.
|
||||||
if (addrlenA == 0 && addrlenB == 0)
|
if (addrA->addrlen == 0 && addrB->addrlen == 0)
|
||||||
return 0;
|
return 0;
|
||||||
// If either sockaddr is truncated, then we compare the bytes we have.
|
// If either sockaddr is truncated, then we compare the bytes we have.
|
||||||
if (addrlenA < sizeof addrA->sa_family || addrlenB < sizeof addrB->sa_family) {
|
if (addrA->addrlen < sizeof addrA->addr.sa_family || addrB->addrlen < sizeof addrB->addr.sa_family) {
|
||||||
int c = memcmp(addrA, addrB, addrlenA < addrlenB ? addrlenA : addrlenB);
|
int c = memcmp(addrA, addrB, addrA->addrlen < addrB->addrlen ? addrA->addrlen : addrB->addrlen);
|
||||||
if (c == 0)
|
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;
|
return c;
|
||||||
}
|
}
|
||||||
// Order first by address family.
|
// Order first by address family.
|
||||||
if (addrA->sa_family < addrB->sa_family)
|
if (addrA->addr.sa_family < addrB->addr.sa_family)
|
||||||
return -1;
|
return -1;
|
||||||
if (addrA->sa_family > addrB->sa_family)
|
if (addrA->addr.sa_family > addrB->addr.sa_family)
|
||||||
return 1;
|
return 1;
|
||||||
// Both addresses are in the same family...
|
// Both addresses are in the same family...
|
||||||
switch (addrA->sa_family) {
|
switch (addrA->addr.sa_family) {
|
||||||
case AF_UNIX: {
|
case AF_UNIX: {
|
||||||
unsigned pathlenA = addrlenA - sizeof ((const struct sockaddr_un *)addrA)->sun_family;
|
unsigned pathlenA = addrA->addrlen - sizeof (addrA->addr_un.sun_family);
|
||||||
unsigned pathlenB = addrlenB - sizeof ((const struct sockaddr_un *)addrB)->sun_family;
|
unsigned pathlenB = addrB->addrlen - sizeof (addrB->addr_un.sun_family);
|
||||||
int c;
|
int c;
|
||||||
if ( pathlenA > 1 && pathlenB > 1
|
if ( pathlenA > 1 && pathlenB > 1
|
||||||
&& ((const struct sockaddr_un *)addrA)->sun_path[0] == '\0'
|
&& addrA->addr_un.sun_path[0] == '\0'
|
||||||
&& ((const struct sockaddr_un *)addrB)->sun_path[0] == '\0'
|
&& addrB->addr_un.sun_path[0] == '\0'
|
||||||
) {
|
) {
|
||||||
// Both abstract sockets - just compare names, nul bytes are not terminators.
|
// Both abstract sockets - just compare names, nul bytes are not terminators.
|
||||||
c = memcmp(&((const struct sockaddr_un *)addrA)->sun_path[1],
|
c = memcmp(&addrA->addr_un.sun_path[1],
|
||||||
&((const struct sockaddr_un *)addrB)->sun_path[1],
|
&addrB->addr_un.sun_path[1],
|
||||||
(pathlenA < pathlenB ? pathlenA : pathlenB) - 1);
|
(pathlenA < pathlenB ? pathlenA : pathlenB) - 1);
|
||||||
} else {
|
} else {
|
||||||
// Either or both are named local file sockets. If the file names are identical up to the
|
// 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
|
// 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.
|
// character is a nul, ahead of all non-empty file socket names.
|
||||||
c = strncmp(((const struct sockaddr_un *)addrA)->sun_path,
|
c = strncmp(addrA->addr_un.sun_path,
|
||||||
((const struct sockaddr_un *)addrB)->sun_path,
|
addrB->addr_un.sun_path,
|
||||||
(pathlenA < pathlenB ? pathlenA : pathlenB));
|
(pathlenA < pathlenB ? pathlenA : pathlenB));
|
||||||
}
|
}
|
||||||
if (c == 0)
|
if (c == 0)
|
||||||
@ -153,9 +159,10 @@ int cmp_sockaddr(const struct sockaddr *addrA, socklen_t addrlenA, const struct
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Fall back to comparing raw data bytes.
|
// 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)
|
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;
|
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);
|
DEBUGF("setsockopt(%d, SOL_SOCKET, SO_RCVBUF, &%u, %u)", sock, buffer_size, (unsigned)sizeof buffer_size);
|
||||||
return 0;
|
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 "http_server.h"
|
||||||
#include "strbuf_helpers.h"
|
#include "strbuf_helpers.h"
|
||||||
#include "str.h"
|
#include "str.h"
|
||||||
|
#include "socket.h"
|
||||||
|
|
||||||
static inline strbuf _toprint(strbuf sb, char c)
|
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;
|
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)
|
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
|
// 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);
|
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)))
|
#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.
|
/* Append a strftime(3) string.
|
||||||
* @author Andrew Bettison <andrew@servalproject.com>
|
* @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++;
|
call->local.sequence++;
|
||||||
|
|
||||||
overlay_mdp_dispatch(&mdp,0,NULL,0);
|
overlay_mdp_dispatch(&mdp, NULL);
|
||||||
|
|
||||||
return 0;
|
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;
|
mdp.out.queue=OQ_ISOCHRONOUS_VOICE;
|
||||||
|
|
||||||
overlay_mdp_dispatch(&mdp,0,NULL,0);
|
overlay_mdp_dispatch(&mdp, NULL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user