int main (void) { zctx_t *ctx = zctx_new (); udp_t *udp = udp_new (PING_PORT_NUMBER); byte buffer [PING_MSG_SIZE]; zmq_pollitem_t pollitems [] = {{ NULL, udp_handle (udp), ZMQ_POLLIN, 0 }}; // Send first ping right away uint64_t ping_at = zclock_time (); while (!zctx_interrupted) { long timeout = (long) (ping_at - zclock_time ()); if (timeout < 0) timeout = 0; if (zmq_poll (pollitems, 1, timeout * ZMQ_POLL_MSEC) == -1) break; // Interrupted // Someone answered our ping if (pollitems [0].revents & ZMQ_POLLIN) udp_recv (udp, buffer, PING_MSG_SIZE); if (zclock_time () >= ping_at) { puts ("Pinging peers..."); buffer [0] = '!'; udp_send (udp, buffer, PING_MSG_SIZE); ping_at = zclock_time () + PING_INTERVAL; } } udp_destroy (&udp); zctx_destroy (&ctx); return 0; }
void ip_handle() { int * data = ethernet_rx_data + ETHERNET_HDR_LEN; // not IPv4 or header is longer than 20bit if(data[IP_VERSION] != IP_VERSION_VAL) return; if (data[IP_DST] != IP_ADDR[0] || data[IP_DST + 1] != IP_ADDR[1] || data[IP_DST + 2] != IP_ADDR[2] || data[IP_DST + 3] != IP_ADDR[3]) { //cprintf("IP destination not correct.\n"); return; } int length = (data[IP_TOTAL_LEN] << 8) | data[IP_TOTAL_LEN + 1]; length -= 20; // ip header if(data[IP_PROTOCAL] == IP_PROTOCAL_ICMP) icmp_handle(length); else if(data[IP_PROTOCAL] == IP_PROTOCAL_TCP) tcp_handle(length); else if (data[IP_PROTOCAL] == IP_PROTOCAL_UDP) { //cprintf("udp\n"); udp_handle(length); } else cprintf("unknown protocal %x\n", data[IP_PROTOCAL]); }
static void* run_discovery(void* data) { discovery_opts_t* opts = (discovery_opts_t*)data; char ip[INET_ADDRSTRLEN] = { '\0' }; const char* interface = opts->interface; udp_t *udp = udp_new(PING_PORT_NUMBER, interface); assert(udp); struct pollfd ufds[1]; int ret; time_t t0, t1; beacon_t beacon; uuid_t uuid; beacon_t recv; peers_t* peers = peers_new(); struct in_addr addr; find_my_ip(&addr, NULL); uuid_generate(uuid); beacon_fill(&beacon, (uint8_t*)BEACON_PROTOCOL, BEACON_VERSION, uuid, addr, htons(47473)); ufds[0].fd = udp_handle(udp); ufds[0].events = POLLIN; t0 = time(NULL); t1 = time(NULL); struct sockaddr_in sockaddr; socklen_t si_len = sizeof(struct sockaddr_in); while (1) { t1 = time(NULL); if ((long)(t1 - t0) >= PING_INTERVAL) { ret = udp_send(udp, (uint8_t*)(&beacon), sizeof(beacon_t)); assert(ret == sizeof(beacon_t)); t0 = time(NULL); } ret = poll(ufds, 1, 200); if (ret == -1) { printf("Error: poll returned -1\n"); break; } else if (ret == 0) { continue; } if (ufds[0].revents & POLLIN) { ret = udp_recv(udp, (uint8_t*)&recv, sizeof(beacon_t), &sockaddr, si_len); if (ret == sizeof(beacon_t) && beacon_check(&recv, (uint8_t*)BEACON_PROTOCOL, BEACON_VERSION)) { if (uuid_compare(uuid, recv.uuid) != 0) { peer_t* peer = peers_exist(peers, recv.uuid); if (!peer) { inet_ntop(sockaddr.sin_family, &sockaddr.sin_addr, ip, INET_ADDRSTRLEN); peer = peer_new(recv.uuid, ip, recv.port); peers_add(peers, peer); opts->add_peer_cb((void*)peer); } peer_is_alive(peer); } } } peers_check(peers); } peers_destroy(&peers); udp_destroy(&udp); return NULL; }