/** * Activity on our incoming socket. Read data from the * incoming connection. * * @param cls the `struct NatActivity` * @param tc scheduler context */ static void do_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct NatActivity *na = cls; struct GNUNET_NAT_Test *tst; uint16_t data; na->rtask = NULL; tst = na->h; GNUNET_CONTAINER_DLL_remove (tst->na_head, tst->na_tail, na); if ((NULL != tc->write_ready) && (GNUNET_NETWORK_fdset_isset (tc->read_ready, na->sock)) && (sizeof (data) == GNUNET_NETWORK_socket_recv (na->sock, &data, sizeof (data)))) { if (data == tst->data) tst->report (tst->report_cls, GNUNET_NAT_ERROR_SUCCESS); else LOG (GNUNET_ERROR_TYPE_DEBUG, "Received data does not match expected value\n"); } else LOG (GNUNET_ERROR_TYPE_DEBUG, "Failed to receive data from inbound connection\n"); GNUNET_NETWORK_socket_close (na->sock); GNUNET_free (na); }
/** * Activity on our incoming socket. Read data from the * incoming connection. * * @param cls the `struct GNUNET_NAT_Test` * @param tc scheduler context */ static void do_udp_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_NAT_Test *tst = cls; uint16_t data; tst->ltask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, tst->lsock, &do_udp_read, tst); if ((NULL != tc->write_ready) && (GNUNET_NETWORK_fdset_isset (tc->read_ready, tst->lsock)) && (sizeof (data) == GNUNET_NETWORK_socket_recv (tst->lsock, &data, sizeof (data)))) { if (data == tst->data) tst->report (tst->report_cls, GNUNET_NAT_ERROR_SUCCESS); else LOG (GNUNET_ERROR_TYPE_DEBUG, "Received data mismatches expected value\n"); } else LOG (GNUNET_ERROR_TYPE_DEBUG, "Failed to receive data from inbound connection\n"); }
/** * Activity on our incoming socket. Read data from the * incoming connection. * * @param cls * @param tc scheduler context */ static void do_udp_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_NAT_AutoHandle *ah = cls; unsigned char reply_buf[1024]; ssize_t rlen; struct sockaddr_in answer; if ((0 != (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY)) && (GNUNET_NETWORK_fdset_isset (tc->read_ready, lsock4))) { rlen = GNUNET_NETWORK_socket_recv (lsock4, reply_buf, sizeof (reply_buf)); //Lets handle the packet memset(&answer, 0, sizeof(struct sockaddr_in)); if(ah->phase == AUTO_NAT_PUNCHED) { //Destroy the connection GNUNET_NETWORK_socket_close (lsock4); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "The external server was able to connect back"); ah->connected_back = GNUNET_YES; next_phase (ah); } else { if (GNUNET_OK == GNUNET_NAT_stun_handle_packet (reply_buf, rlen, &answer)) { //Process the answer process_stun_reply (&answer, ah); } else { next_phase (ah); } } } else { GNUNET_log (GNUNET_ERROR_TYPE_INFO, "TIMEOUT while waiting for an answer\n"); if (ah->phase == AUTO_NAT_PUNCHED) { stop_stun(); } next_phase (ah); } }
/** * This function is called once we either timeout * or have data ready to read. * * @param cls connection to read from * @param tc scheduler context */ static void receive_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_CONNECTION_Handle *connection = cls; char buffer[connection->max]; ssize_t ret; GNUNET_CONNECTION_Receiver receiver; connection->read_task = GNUNET_SCHEDULER_NO_TASK; if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) { /* ignore shutdown request, go again immediately */ connection->read_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining (connection->receive_timeout), connection->sock, &receive_ready, connection); return; } if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Receive from `%s' encounters error: timeout (%p)\n", GNUNET_a2s (connection->addr, connection->addrlen), GNUNET_TIME_absolute_get_duration (connection->receive_timeout).rel_value, connection); signal_receive_timeout (connection); return; } if (NULL == connection->sock) { /* connect failed for good */ signal_receive_error (connection, ECONNREFUSED); return; } GNUNET_assert (GNUNET_NETWORK_fdset_isset (tc->read_ready, connection->sock)); RETRY: ret = GNUNET_NETWORK_socket_recv (connection->sock, buffer, connection->max); if (-1 == ret) { if (EINTR == errno) goto RETRY; signal_receive_error (connection, errno); return; } LOG (GNUNET_ERROR_TYPE_DEBUG, "receive_ready read %u/%u bytes from `%s' (%p)!\n", (unsigned int) ret, connection->max, GNUNET_a2s (connection->addr, connection->addrlen), connection); GNUNET_assert (NULL != (receiver = connection->receiver)); connection->receiver = NULL; receiver (connection->receiver_cls, buffer, ret, connection->addr, connection->addrlen, 0); }
/** * Activity on our incoming socket. Read data from the * incoming connection. * * @param cls */ static void do_udp_read (void *cls) { //struct GNUNET_NAT_Test *tst = cls; unsigned char reply_buf[1024]; ssize_t rlen; struct sockaddr_in answer; const struct GNUNET_SCHEDULER_TaskContext *tc; ltask4 = NULL; tc = GNUNET_SCHEDULER_get_task_context (); if ( (0 == (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY)) || (! GNUNET_NETWORK_fdset_isset (tc->read_ready, lsock4)) ) { fprintf (stderr, "Timeout waiting for STUN response\n"); stop(); } rlen = GNUNET_NETWORK_socket_recv (lsock4, reply_buf, sizeof (reply_buf)); memset (&answer, 0, sizeof(struct sockaddr_in)); if (GNUNET_OK != GNUNET_NAT_stun_handle_packet (reply_buf, rlen, &answer)) { fprintf (stderr, "Unexpected UDP packet, trying to read more\n"); ltask4 = GNUNET_SCHEDULER_add_read_net (TIMEOUT, lsock4, &do_udp_read, NULL); return; } ret = 0; print_answer (&answer); stop (); }