void handle_message(cjdnsadmin_t *adm, char *buffer, ssize_t len) { // TODO: fix memory leak struct bencode *b = ben_decode(buffer, len); if (!b) { fprintf(stderr, "bencode error: %lu\n",len); printf("message from cjdns: \"%*s\"\n", (int)len, buffer); return; } // Get IPs struct bencode *table = ben_dict_get_by_str(b, "routingTable"); size_t i, num_items = ben_list_len(table); for (i = 0; i < num_items; i++) { struct bencode *item = ben_list_get(table, i); struct bencode *ip = ben_dict_get_by_str(item, "ip"); if (ben_is_str(ip)) { const char *ip_str = ben_str_val(ip); if (adm->on_found_ip) { (*adm->on_found_ip)(adm->on_found_ip_obj, ip_str); } } } // check if there is more struct bencode *more = ben_dict_get_by_str(b, "more"); int more_int = more && ben_is_int(more) && ben_int_val(more); if (more_int == 1) { // get the next page of the routing table adm->fetch_peers_page++; cjdnsadmin_fetch_peers(adm); } else { // start from the first page next time adm->fetch_peers_page = 0; } ben_free(b); }
void p2p_error(BEN * packet, IP * from) { BEN *e = NULL; BEN *code = NULL; BEN *msg = NULL; ITEM *i = NULL; #if 0 BEN *t = NULL; /* Transaction ID */ t = ben_dict_search_str(packet, "t"); if (!ben_is_str(t)) { info(_log, from, "Missing transaction ID from"); return; } if (ben_str_i(t) != TID_SIZE) { info(_log, from, "Broken transaction ID from"); return; } #endif /* The error */ e = ben_dict_search_str(packet, "e"); if (!ben_is_list(e)) { info(_log, from, "Missing or broken error message from"); return; } /* Error code */ i = list_start(e->v.l); code = list_value(i); if (!ben_is_int(code)) { info(_log, from, "Broken error code from"); return; } /* Error message */ i = list_stop(e->v.l); msg = list_value(i); if (!ben_is_str(msg)) { info(_log, from, "Broken error message from"); return; } if (ben_str_i(msg) > 100) { info(_log, from, "Error message too big from"); return; } /* Notification */ info(_log, from, "ERROR %li: \"%s\" from", code->v.i, ben_str_s(msg)); }
void p2p_announce_get_request(BEN * arg, UCHAR * node_id, BEN * tid, IP * from) { BEN *info_hash = NULL; BEN *token = NULL; BEN *port = NULL; /* info_hash */ info_hash = ben_dict_search_str(arg, "info_hash"); if (!p2p_is_hash(info_hash)) { info(_log, from, "Missing or broken info_hash from"); return; } /* Token */ token = ben_dict_search_str(arg, "token"); if (!ben_is_str(token) || ben_str_i(token) > TOKEN_SIZE_MAX) { info(_log, from, "Missing or broken token from"); return; } if (!tkn_validate(ben_str_s(token))) { info(_log, from, "Invalid token from"); return; } /* Port */ port = ben_dict_search_str(arg, "port"); if (!ben_is_int(port)) { info(_log, from, "Missing or broken port from"); return; } if (port->v.i < 1 || port->v.i > 65535) { info(_log, from, "Invalid port number from"); return; } /* Store info_hash */ val_put(ben_str_s(info_hash), node_id, port->v.i, from); /* Send success message */ send_announce_reply(from, ben_str_s(tid), ben_str_i(tid)); }