Respond to directory publish requests with success / failure

This commit is contained in:
Jeremy Lakeman 2014-09-01 12:05:08 +09:30
parent 97e7de03cd
commit 097f72f04f
3 changed files with 64 additions and 34 deletions

View File

@ -38,6 +38,7 @@ struct item{
};
struct item *root=NULL;
static uint8_t allow_duplicates = 1;
static struct item *create_item(const char *key){
struct item *ret=calloc(1,sizeof(struct item));
@ -62,7 +63,7 @@ static struct item *find_item(const char *key){
return NULL;
}
static void add_item(char *key, char *value){
static int add_item(const char *key, const char *value){
struct item *item = root, **last_ptr=&root;
while(item){
int c=strcmp(item->key, key);
@ -70,8 +71,9 @@ static void add_item(char *key, char *value){
c=strcmp(item->value, value);
if (c==0){
item->expires = gettime_ms()+1200000;
return;
}
return 1;
}else if(!allow_duplicates)
return -1;
}
if (c<0){
last_ptr = &item->_left;
@ -87,38 +89,47 @@ static void add_item(char *key, char *value){
item->value[sizeof(item->value) -1]=0;
// expire after 20 minutes
item->expires = gettime_ms()+1200000;
// used by tests
fprintf(stderr, "PUBLISHED \"%s\" = \"%s\"\n", key, value);
return 0;
}
static void add_record(int mdp_sockfd){
int ttl;
overlay_mdp_frame mdp;
static int add_record(int mdp_sockfd){
struct mdp_header header;
uint8_t payload[MDP_MTU];
if (overlay_mdp_recv(mdp_sockfd, &mdp, MDP_PORT_DIRECTORY, &ttl))
return;
ssize_t len = mdp_recv(mdp_sockfd, &header, payload, sizeof payload);
if (len==-1)
return WHY_perror("mdp_recv");
if (mdp.packetTypeAndFlags&MDP_NOCRYPT){
fprintf(stderr, "Only encrypted packets will be considered for publishing\n");
return;
}
if (header.flags & (MDP_FLAG_NO_CRYPT|MDP_FLAG_NO_SIGN))
return WHY("Only encrypted packets will be considered for publishing\n");
// make sure the payload is a NULL terminated string
mdp.out.payload[mdp.out.payload_length]=0;
payload[len]=0;
char *did=(char *)mdp.out.payload;
int i=0;
while(i<mdp.out.payload_length && mdp.out.payload[i] && mdp.out.payload[i]!='|')
const char *did=(const char *)payload;
unsigned i=0;
while(i<len && payload[i] && payload[i]!='|')
i++;
mdp.out.payload[i]=0;
char *name = (char *)mdp.out.payload+i+1;
char *sid = alloca_tohex_sid_t(mdp.out.src.sid);
payload[i]=0;
const char *name = (const char *)payload+i+1;
const char *sid = alloca_tohex_sid_t(header.remote.sid);
// TODO check that did is a valid phone number
char url[256];
snprintf(url, sizeof(url), "sid://%s/local/%s|%s|%s", sid, did, did, name);
add_item(did, url);
// TODO only add whitelisted entries
int r=add_item(did, url);
if (r==0){
// used by tests
fprintf(stderr, "PUBLISHED \"%s\" = \"%s\"\n", did, url);
}
uint8_t response = (r==-1 ? 0:1);
if (mdp_send(mdp_sockfd, &header, &response, sizeof response)==-1)
return WHY_perror("mdp_send");
return 0;
}
static void respond(char *token, struct item *item, char *key){
@ -188,20 +199,14 @@ int main(void){
struct pollfd fds[2];
int mdp_sockfd;
if ((mdp_sockfd = overlay_mdp_client_socket()) < 0)
if ((mdp_sockfd = mdp_socket()) < 0)
return WHY("Cannot create MDP socket");
// bind for incoming directory updates
sid_t srcsid;
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, MDP_PORT_DIRECTORY)) {
overlay_mdp_client_close(mdp_sockfd);
return WHY("Could not bind to MDP socket");
}
struct mdp_sockaddr local_addr = {.sid = BIND_PRIMARY, .port = MDP_PORT_DIRECTORY};
if (mdp_bind(mdp_sockfd, &local_addr)==-1)
return WHY_perror("mdp_bind");
fds[0].fd = STDIN_FILENO;
fds[0].events = POLLIN;
@ -224,6 +229,6 @@ int main(void){
}
}
overlay_mdp_client_close(mdp_sockfd);
mdp_close(mdp_sockfd);
return 0;
}

View File

@ -155,6 +155,28 @@ ssize_t _mdp_recv(struct __sourceloc __whence, int socket, struct mdp_header *he
return len - sizeof(struct mdp_header);
}
int _mdp_bind(struct __sourceloc __whence, int socket, struct mdp_sockaddr *local_addr)
{
struct mdp_header mdp_header;
bzero(&mdp_header, sizeof(mdp_header));
mdp_header.local = *local_addr;
mdp_header.remote.port = MDP_LISTEN;
mdp_header.remote.sid = SID_ANY;
mdp_header.flags = MDP_FLAG_BIND;
if (_mdp_send(__whence, socket, &mdp_header, NULL, 0)==-1)
return -1;
if (_mdp_recv(__whence, socket, &mdp_header, NULL, 0)==-1)
return -1;
if (mdp_header.flags & MDP_FLAG_ERROR){
errno = EBADMSG;
return -1;
}
*local_addr = mdp_header.local;
return 0;
}
int _mdp_poll(struct __sourceloc UNUSED(__whence), int socket, time_ms_t timeout_ms)
{
// TODO make overlay_mdp_client_poll() take __whence arg

View File

@ -145,11 +145,14 @@ int _mdp_send(struct __sourceloc, int socket, const struct mdp_header *header, c
ssize_t _mdp_recv(struct __sourceloc, int socket, struct mdp_header *header, uint8_t *payload, size_t max_len);
int _mdp_poll(struct __sourceloc, int socket, time_ms_t timeout_ms);
ssize_t mdp_poll_recv(int mdp_sock, time_ms_t deadline, struct mdp_header *rev_header, unsigned char *payload, size_t buffer_size);
int _mdp_bind(struct __sourceloc __whence, int socket, struct mdp_sockaddr *local_addr);
#define mdp_socket() _mdp_socket(__WHENCE__)
#define mdp_close(s) _mdp_close(__WHENCE__, (s))
#define mdp_send(s,h,p,l) _mdp_send(__WHENCE__, (s), (h), (p), (l))
#define mdp_recv(s,h,p,l) _mdp_recv(__WHENCE__, (s), (h), (p), (l))
#define mdp_poll(s,t) _mdp_poll(__WHENCE__, (s), (t))
#define mdp_bind(s,a) _mdp_bind(__WHENCE__, (s), (a))
/* Client-side MDP function */
int overlay_mdp_client_socket(void);