/** * Try to send 'data' to the * IP 'dst_ipv4' at port 'dport' via TCP. * * @param dst_ipv4 target IP * @param dport target port * @param data data to send */ static void try_send_tcp (uint32_t dst_ipv4, uint16_t dport, uint16_t data) { struct GNUNET_NETWORK_Handle *s; struct sockaddr_in sa; struct TcpContext *ctx; s = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0); if (NULL == s) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "socket"); return; } memset (&sa, 0, sizeof (sa)); sa.sin_family = AF_INET; #if HAVE_SOCKADDR_IN_SIN_LEN sa.sin_len = sizeof (sa); #endif sa.sin_addr.s_addr = dst_ipv4; sa.sin_port = htons (dport); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending TCP message to `%s'\n", GNUNET_a2s ((struct sockaddr *) &sa, sizeof (sa))); if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (s, (const struct sockaddr *) &sa, sizeof (sa))) && (errno != EINPROGRESS)) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "connect"); GNUNET_NETWORK_socket_close (s); return; } ctx = GNUNET_malloc (sizeof (struct TcpContext)); ctx->s = s; ctx->data = data; GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_SECONDS, s, &tcp_send, ctx); }
/** * Try to send 'data' to the * IP 'dst_ipv4' at port 'dport' via UDP. * * @param dst_ipv4 target IP * @param dport target port * @param data data to send */ static void try_send_udp (uint32_t dst_ipv4, uint16_t dport, uint16_t data) { struct GNUNET_NETWORK_Handle *s; struct sockaddr_in sa; s = GNUNET_NETWORK_socket_create (AF_INET, SOCK_DGRAM, 0); if (NULL == s) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "socket"); return; } memset (&sa, 0, sizeof (sa)); sa.sin_family = AF_INET; #if HAVE_SOCKADDR_IN_SIN_LEN sa.sin_len = sizeof (sa); #endif sa.sin_addr.s_addr = dst_ipv4; sa.sin_port = htons (dport); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending UDP packet to `%s'\n", GNUNET_a2s ((struct sockaddr *) &sa, sizeof (sa))); if (-1 == GNUNET_NETWORK_socket_sendto (s, &data, sizeof (data), (const struct sockaddr *) &sa, sizeof (sa))) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "sendto"); GNUNET_NETWORK_socket_close (s); }
/** * Clears a bit from bitArray if the respective usage * counter on the disk hits/is zero. * * @param bitArray memory area to set the bit in * @param bitIdx which bit to test * @param fh A file to keep the 4bit address usage counters in */ static void decrementBit (char *bitArray, unsigned int bitIdx, const struct GNUNET_DISK_FileHandle *fh) { off_t fileslot; unsigned char value; unsigned int high; unsigned int low; unsigned int targetLoc; if (GNUNET_DISK_handle_invalid (fh)) return; /* cannot decrement! */ /* Each char slot in the counter file holds two 4 bit counters */ fileslot = bitIdx / 2; targetLoc = bitIdx % 2; if (GNUNET_SYSERR == GNUNET_DISK_file_seek (fh, fileslot, GNUNET_DISK_SEEK_SET)) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "seek"); return; } if (1 != GNUNET_DISK_file_read (fh, &value, 1)) value = 0; low = value & 0xF; high = (value & 0xF0) >> 4; /* decrement, but once we have reached the max, never go back! */ if (targetLoc == 0) { if ((low > 0) && (low < 0xF)) low--; if (low == 0) { clearBit (bitArray, bitIdx); } } else { if ((high > 0) && (high < 0xF)) high--; if (high == 0) { clearBit (bitArray, bitIdx); } } value = ((high << 4) | low); if (GNUNET_SYSERR == GNUNET_DISK_file_seek (fh, fileslot, GNUNET_DISK_SEEK_SET)) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "seek"); return; } GNUNET_assert (1 == GNUNET_DISK_file_write (fh, &value, 1)); }
static void stop_arm (struct PeerContext *p) { if (0 != GNUNET_OS_process_kill (p->arm_proc, GNUNET_TERM_SIG)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); if (GNUNET_OS_process_wait (p->arm_proc) != GNUNET_OK) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc)); GNUNET_OS_process_destroy (p->arm_proc); p->arm_proc = NULL; GNUNET_CONFIGURATION_destroy (p->cfg); }
/** * Shutdown nicely */ static void do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { GNUNET_STREAM_close (peer1.socket); if (NULL != peer2.socket) GNUNET_STREAM_close (peer2.socket); if (NULL != peer2_listen_socket) GNUNET_STREAM_listen_close (peer2_listen_socket); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: shutdown\n"); if (0 != abort_task) { GNUNET_SCHEDULER_cancel (abort_task); } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: arm\n"); if (0 != GNUNET_OS_process_kill (arm_pid, SIGTERM)) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Wait\n"); /* Free the duplicated configuration */ GNUNET_CONFIGURATION_destroy (config_peer1); GNUNET_CONFIGURATION_destroy (config_peer2); GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (arm_pid)); GNUNET_OS_process_destroy (arm_pid); }
/** * Create and initialize a listen socket for the server. * * @return NULL on error, otherwise the listen socket */ static struct GNUNET_NETWORK_Handle * open_listen_socket () { const static int on = 1; struct sockaddr_in sa; struct GNUNET_NETWORK_Handle *desc; memset (&sa, 0, sizeof (sa)); #if HAVE_SOCKADDR_IN_SIN_LEN sa.sin_len = sizeof (sa); #endif sa.sin_family = AF_INET; sa.sin_port = htons (PORT); desc = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0); GNUNET_assert (desc != 0); if (GNUNET_NETWORK_socket_setsockopt (desc, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK) GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "setsockopt"); if (GNUNET_OK != GNUNET_NETWORK_socket_bind (desc, (const struct sockaddr *) &sa, sizeof (sa))) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "bind"); GNUNET_assert (0); } GNUNET_NETWORK_socket_listen (desc, 5); return desc; }
static int check () { char *const argv[] = { "test-sensor-api", NULL }; struct GNUNET_GETOPT_CommandLineOption options[] = { GNUNET_GETOPT_OPTION_END }; struct GNUNET_OS_Process *proc; char *path = GNUNET_OS_get_libexec_binary_path ("gnunet-service-sensor"); if (NULL == path) { fprintf (stderr, "Service executable not found `%s'\n", "gnunet-service-sensor"); return -1; } proc = GNUNET_OS_start_process (GNUNET_NO, GNUNET_OS_INHERIT_STD_ALL, NULL, NULL, NULL, path, "gnunet-service-sensor", NULL); GNUNET_free (path); GNUNET_assert (NULL != proc); GNUNET_PROGRAM_run (1, argv, "test-sensor-api", "nohelp", options, &run, &ok); if (0 != GNUNET_OS_process_kill (proc, SIGTERM)) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); ok = 1; } GNUNET_OS_process_wait (proc); GNUNET_OS_process_destroy (proc); return ok; }
/** * Test killing via pipe. */ static int check_instant_kill () { char *fn; #if !WINDOWS GNUNET_asprintf (&fn, "cat"); #else GNUNET_asprintf (&fn, "w32cat"); #endif hello_pipe_stdin = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_YES, GNUNET_NO); hello_pipe_stdout = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES); if ((hello_pipe_stdout == NULL) || (hello_pipe_stdin == NULL)) { GNUNET_free (fn); return 1; } proc = GNUNET_OS_start_process (GNUNET_YES, GNUNET_OS_INHERIT_STD_ERR, hello_pipe_stdin, hello_pipe_stdout, fn, "gnunet-service-resolver", "-", NULL); if (0 != GNUNET_OS_process_kill (proc, SIGTERM)) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); } GNUNET_free (fn); GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (proc)); GNUNET_OS_process_destroy (proc); proc = NULL; GNUNET_DISK_pipe_close (hello_pipe_stdout); GNUNET_DISK_pipe_close (hello_pipe_stdin); return 0; }
/** * Test killing via pipe. */ static int check_instant_kill () { char *fn; hello_pipe_stdin = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_YES, GNUNET_NO); hello_pipe_stdout = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES); if ((hello_pipe_stdout == NULL) || (hello_pipe_stdin == NULL)) { return 1; } fn = GNUNET_OS_get_libexec_binary_path ("gnunet-service-resolver"); proc = GNUNET_OS_start_process (GNUNET_YES, GNUNET_OS_INHERIT_STD_ERR, hello_pipe_stdin, hello_pipe_stdout, NULL, fn, "gnunet-service-resolver", "-", NULL); if (0 != GNUNET_OS_process_kill (proc, GNUNET_TERM_SIG)) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); } GNUNET_free (fn); GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (proc)); GNUNET_OS_process_destroy (proc); proc = NULL; GNUNET_DISK_pipe_close (hello_pipe_stdout); GNUNET_DISK_pipe_close (hello_pipe_stdin); return 0; }
/** * Shutdown nicely */ static void do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: shutdown\n"); if (0 != abort_task) { GNUNET_SCHEDULER_cancel (abort_task); } if (NULL != t) { GNUNET_MESH_tunnel_destroy(t); } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: D1\n"); if (NULL != mesh_peer_1) { GNUNET_MESH_disconnect (mesh_peer_1); } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: D2\n"); if (NULL != mesh_peer_2) { GNUNET_MESH_disconnect (mesh_peer_2); } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: arm\n"); if (0 != GNUNET_OS_process_kill (arm_pid, SIGTERM)) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Wait\n"); GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (arm_pid)); GNUNET_OS_process_destroy (arm_pid); }
static void waitpid_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct PeerContext *p = cls; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Killing ARM process.\n"); if (0 != GNUNET_OS_process_kill (p->arm_proc, GNUNET_TERM_SIG)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); if (GNUNET_OS_process_wait (p->arm_proc) != GNUNET_OK) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc)); GNUNET_OS_process_destroy (p->arm_proc); p->arm_proc = NULL; GNUNET_CONFIGURATION_destroy (p->cfg); }
/** * Activity on our listen socket. Accept the * incoming connection. * * @param cls the `struct GNUNET_NAT_Test` * @param tc scheduler context */ static void do_accept (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_NAT_Test *tst = cls; struct GNUNET_NETWORK_Handle *s; struct NatActivity *wl; tst->ltask = NULL; if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) return; tst->ltask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, tst->lsock, &do_accept, tst); s = GNUNET_NETWORK_socket_accept (tst->lsock, NULL, NULL); if (NULL == s) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_INFO, "accept"); return; /* odd error */ } LOG (GNUNET_ERROR_TYPE_DEBUG, "Got an inbound connection, waiting for data\n"); wl = GNUNET_new (struct NatActivity); wl->sock = s; wl->h = tst; wl->rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, wl->sock, &do_read, wl); GNUNET_CONTAINER_DLL_insert (tst->na_head, tst->na_tail, wl); }
static void end_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ending phase %d, ok is %d\n", phase, ok); if (NULL != proc) { if (0 != GNUNET_OS_process_kill (proc, GNUNET_TERM_SIG)) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); } GNUNET_OS_process_wait (proc); GNUNET_OS_process_destroy (proc); proc = NULL; } if (NULL != read_task) { GNUNET_SCHEDULER_cancel (read_task); read_task = NULL; } GNUNET_DISK_pipe_close (pipe_stdout); if (ok == 1) { if (phase < 9) { phase += 1; runone (); } else ok = 0; } else GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "failing\n"); }
/** * Main function run with scheduler. */ static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) { //Lets create the socket lsock4 = bind_v4 (); if (NULL == lsock4) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind"); GNUNET_SCHEDULER_shutdown (); return; } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Service listens on port %u\n", (unsigned int) port); rh = GNUNET_NAT_stun_make_request (stun_server, stun_port, lsock4, &request_callback, NULL); GNUNET_SCHEDULER_add_delayed (TIMEOUT, &stop, NULL); }
int main (int argc, char *argv[]) { int ret = 0; struct GNUNET_NETWORK_Handle *s = NULL; GNUNET_log_setup ("test-service", "WARNING", NULL); ret += check (); ret += check (); // FIXME #ifndef MINGW s = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0); #endif if (NULL == s) { if ((errno == ENOBUFS) || (errno == ENOMEM) || (errno == ENFILE) || (errno == EACCES)) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket"); return 1; } FPRINTF (stderr, "IPv6 support seems to not be available (%s), not testing it!\n", strerror (errno)); } else { GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (s)); ret += check6 (); } ret += check_start_stop (); return ret; }
void http_check_ipv6 (struct Plugin *plugin) { struct GNUNET_NETWORK_Handle *desc = NULL; if (plugin->ipv6 == GNUNET_YES) { /* probe IPv6 support */ desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0); if (NULL == desc) { if ((errno == ENOBUFS) || (errno == ENOMEM) || (errno == ENFILE) || (errno == EACCES)) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket"); } GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, plugin->name, _ ("Disabling IPv6 since it is not supported on this system!\n")); plugin->ipv6 = GNUNET_NO; } else { GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc)); desc = NULL; } GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "Testing IPv6 on this system: %s\n", (plugin->ipv6 == GNUNET_YES) ? "successful" : "failed"); } }
/** * Stop broadcasting subsystem. * * @param plugin */ void stop_broadcast (struct Plugin *plugin) { if (GNUNET_YES == plugin->enable_broadcasting) { /* Disable broadcasting */ while (plugin->broadcast_head != NULL) { struct BroadcastAddress *p = plugin->broadcast_head; if (p->broadcast_task != NULL) { GNUNET_SCHEDULER_cancel (p->broadcast_task); p->broadcast_task = NULL; } if ((GNUNET_YES == plugin->enable_ipv6) && (NULL != plugin->sockv6) && (p->addrlen == sizeof (struct sockaddr_in6))) { /* Create IPv6 multicast request */ struct ipv6_mreq multicastRequest; const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *) p->addr; multicastRequest.ipv6mr_multiaddr = plugin->ipv6_multicast_address.sin6_addr; multicastRequest.ipv6mr_interface = s6->sin6_scope_id; /* Leave the multicast group */ if (GNUNET_OK == GNUNET_NETWORK_socket_setsockopt (plugin->sockv6, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &multicastRequest, sizeof (multicastRequest))) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "setsockopt"); } else { LOG (GNUNET_ERROR_TYPE_DEBUG, "IPv6 multicasting stopped\n"); } } #if LINUX GNUNET_DISK_file_close(p->cryogenic_fd); #endif GNUNET_CONTAINER_DLL_remove (plugin->broadcast_head, plugin->broadcast_tail, p); GNUNET_free (p->addr); GNUNET_free (p); } } /* Destroy MSTs */ if (NULL != plugin->broadcast_mst) { GNUNET_SERVER_mst_destroy (plugin->broadcast_mst); plugin->broadcast_mst = NULL; } }
void stop_broadcast (struct Plugin *plugin) { if (plugin->broadcast_ipv4) { if (plugin->send_ipv4_broadcast_task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (plugin->send_ipv4_broadcast_task); plugin->send_ipv4_broadcast_task = GNUNET_SCHEDULER_NO_TASK; } if (plugin->broadcast_ipv4_mst != NULL) GNUNET_SERVER_mst_destroy (plugin->broadcast_ipv4_mst); while (plugin->ipv4_broadcast_head != NULL) { struct BroadcastAddress *p = plugin->ipv4_broadcast_head; GNUNET_CONTAINER_DLL_remove (plugin->ipv4_broadcast_head, plugin->ipv4_broadcast_tail, p); GNUNET_free (p->addr); GNUNET_free (p); } } if (plugin->broadcast_ipv6) { /* Create IPv6 multicast request */ struct ipv6_mreq multicastRequest; multicastRequest.ipv6mr_multiaddr = plugin->ipv6_multicast_address.sin6_addr; multicastRequest.ipv6mr_interface = 0; /* Join the multicast address */ if (GNUNET_NETWORK_socket_setsockopt (plugin->sockv6, IPPROTO_IPV6, IPV6_LEAVE_GROUP, (char *) &multicastRequest, sizeof (multicastRequest)) != GNUNET_OK) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, setsockopt); } else { LOG (GNUNET_ERROR_TYPE_DEBUG, "IPv6 Broadcasting stopped\n"); } if (plugin->send_ipv6_broadcast_task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (plugin->send_ipv6_broadcast_task); plugin->send_ipv6_broadcast_task = GNUNET_SCHEDULER_NO_TASK; } if (plugin->broadcast_ipv6_mst != NULL) GNUNET_SERVER_mst_destroy (plugin->broadcast_ipv6_mst); } }
/** * Handle STOP-message. * * @param cls closure (always NULL) * @param client identification of the client * @param message the actual message * @return GNUNET_OK to keep the connection open, * GNUNET_SYSERR to close it (signal serious error) */ static void handle_stop (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { struct ServiceList *sl; const char *servicename; uint16_t size; size = ntohs (message->size); size -= sizeof (struct GNUNET_MessageHeader); servicename = (const char *) &message[1]; if ((size == 0) || (servicename[size - 1] != '\0')) { GNUNET_break (0); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Preparing to stop `%s'\n"), servicename); sl = find_service (servicename); if (sl == NULL) { signal_result (client, servicename, GNUNET_ARM_PROCESS_UNKNOWN); return; } sl->is_default = GNUNET_NO; if (GNUNET_YES == in_shutdown) { /* shutdown in progress */ signal_result (client, servicename, GNUNET_ARM_PROCESS_SHUTDOWN); return; } if (sl->killing_client != NULL) { /* killing already in progress */ signal_result (client, servicename, GNUNET_ARM_PROCESS_ALREADY_STOPPING); return; } if (sl->proc == NULL) { /* process is down */ signal_result (client, servicename, GNUNET_ARM_PROCESS_ALREADY_DOWN); return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending kill signal to service `%s', waiting for process to die.\n", servicename); sl->killed_at = GNUNET_TIME_absolute_get (); if (0 != GNUNET_OS_process_kill (sl->proc, SIGTERM)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); sl->killing_client = client; GNUNET_SERVER_client_keep (client); }
/** * Function called whenever a message is received. * * Each time the function must call #GNUNET_MESH_receive_done on the channel * in order to receive the next message. This doesn't need to be immediate: * can be delayed if some processing is done on the message. * * @param cls Closure (set from #GNUNET_MESH_connect). * @param channel Connection to the other end. * @param channel_ctx Place to store local state associated with the channel. * @param message The actual message. * @return #GNUNET_OK to keep the channel open, * #GNUNET_SYSERR to close it (signal serious error). */ static int data_callback (void *cls, struct GNUNET_MESH_Channel *channel, void **channel_ctx, const struct GNUNET_MessageHeader *message) { uint16_t len; ssize_t done; uint16_t off; const char *buf; GNUNET_break (ch == channel); if (GNUNET_YES == echo) { if (0 != listen_port) { /* Just listening to echo incoming messages*/ GNUNET_MESH_notify_transmit_ready (channel, GNUNET_NO, GNUNET_TIME_UNIT_FOREVER_REL, sizeof (struct GNUNET_MessageHeader), &data_ready, NULL); return GNUNET_OK; } else { struct GNUNET_TIME_Relative latency; latency = GNUNET_TIME_absolute_get_duration (echo_time); echo_time = GNUNET_TIME_UNIT_FOREVER_ABS; FPRINTF (stdout, "time: %s\n", GNUNET_STRINGS_relative_time_to_string (latency, GNUNET_NO)); echo_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &send_echo, NULL); } } len = ntohs (message->size) - sizeof (*message); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got %u bytes\n", len); buf = (const char *) &message[1]; off = 0; while (off < len) { done = write (1, &buf[off], len - off); if (done <= 0) { if (-1 == done) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "write"); return GNUNET_SYSERR; } off += done; } return GNUNET_OK; }
/** * Task run for shutdown. * * @param cls closure, NULL if we need to self-restart * @param tc context */ static void shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct ServiceList *pos; struct ServiceList *nxt; struct ServiceListeningInfo *sli; if (GNUNET_SCHEDULER_NO_TASK != child_restart_task) { GNUNET_SCHEDULER_cancel (child_restart_task); child_restart_task = GNUNET_SCHEDULER_NO_TASK; } in_shutdown = GNUNET_YES; /* first, stop listening */ for (pos = running_head; NULL != pos; pos = pos->next) { while (NULL != (sli = pos->listen_head)) { GNUNET_CONTAINER_DLL_remove (pos->listen_head, pos->listen_tail, sli); if (sli->accept_task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (sli->accept_task); sli->accept_task = GNUNET_SCHEDULER_NO_TASK; } GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sli->listen_socket)); GNUNET_free (sli->service_addr); GNUNET_free (sli); } } /* then, shutdown all existing service processes */ nxt = running_head; while (NULL != (pos = nxt)) { nxt = pos->next; if (pos->proc != NULL) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stopping service `%s'\n", pos->name); pos->killed_at = GNUNET_TIME_absolute_get (); if (0 != GNUNET_OS_process_kill (pos->proc, SIGTERM)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); } else { free_service (pos); } } /* finally, should all service processes be already gone, terminate for real */ if (running_head == NULL) do_shutdown (); }
static void stop_arm () { if (NULL != arm) { if (0 != GNUNET_OS_process_kill (arm, SIGTERM)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); GNUNET_OS_process_wait (arm); GNUNET_OS_process_destroy (arm); arm = NULL; } }
int main (int argc, char *const argv[]) { struct GNUNET_GETOPT_CommandLineOption options[] = { GNUNET_GETOPT_OPTION_END }; char *const argv_prog[] = { "test-stun", "-c", "test_stun.conf", NULL }; char *fn; struct GNUNET_OS_Process *proc; GNUNET_log_setup ("test-stun", "WARNING", NULL); /* Lets start resolver */ fn = GNUNET_OS_get_libexec_binary_path ("gnunet-service-resolver"); proc = GNUNET_OS_start_process (GNUNET_YES, GNUNET_OS_INHERIT_STD_OUT_AND_ERR, NULL, NULL, NULL, fn, "gnunet-service-resolver", "-c", "test_stun.conf", NULL); if (NULL == proc) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, "This test was unable to start gnunet-service-resolver, and it is required to run ...\n"); exit(1); } GNUNET_PROGRAM_run (3, argv_prog, "test-stun", "nohelp", options, &run, NULL); /* Now kill the resolver */ if (0 != GNUNET_OS_process_kill (proc, GNUNET_TERM_SIG)) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); } GNUNET_OS_process_wait (proc); GNUNET_OS_process_destroy (proc); proc = NULL; GNUNET_free (fn); return ret; }
static void udp_ipv4_broadcast_send (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct Plugin *plugin = cls; int sent; uint16_t msg_size; char buf[65536] GNUNET_ALIGN; struct BroadcastAddress *baddr; plugin->send_ipv4_broadcast_task = GNUNET_SCHEDULER_NO_TASK; msg_size = prepare_beacon(plugin, (struct UDP_Beacon_Message *) &buf); sent = 0; baddr = plugin->ipv4_broadcast_head; /* just IPv4 */ while ((msg_size > 0) && (baddr != NULL) && (baddr->addrlen == sizeof (struct sockaddr_in))) { struct sockaddr_in *addr = (struct sockaddr_in *) baddr->addr; addr->sin_port = htons (plugin->port); sent = GNUNET_NETWORK_socket_sendto (plugin->sockv4, &buf, msg_size, (const struct sockaddr *) addr, baddr->addrlen); if (sent == GNUNET_SYSERR) { if ((ENETUNREACH == errno) || (ENETDOWN == errno)) { /* "Network unreachable" or "Network down" * * This indicates that we just do not have network connectivity */ GNUNET_log (GNUNET_ERROR_TYPE_BULK | GNUNET_ERROR_TYPE_WARNING, "Network connectivity is down, cannot send beacon!\n"); } else GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sendto"); } else { LOG (GNUNET_ERROR_TYPE_DEBUG, "Sent HELLO beacon broadcast with %i bytes to address %s\n", sent, GNUNET_a2s (baddr->addr, baddr->addrlen)); } baddr = baddr->next; } plugin->send_ipv4_broadcast_task = GNUNET_SCHEDULER_add_delayed (plugin->broadcast_interval, &udp_ipv4_broadcast_send, plugin); }
static void end_task (void *cls) { if (0 != GNUNET_OS_process_kill (proc, GNUNET_TERM_SIG)) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); } GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (proc)); GNUNET_OS_process_destroy (proc); proc = NULL; GNUNET_DISK_pipe_close (hello_pipe_stdout); GNUNET_DISK_pipe_close (hello_pipe_stdin); }
static void end_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { if (0 != GNUNET_OS_process_kill (proc, SIGTERM)) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); } GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (proc)); GNUNET_OS_process_destroy (proc); proc = NULL; GNUNET_DISK_pipe_close (hello_pipe_stdout); GNUNET_DISK_pipe_close (hello_pipe_stdin); }
/** * Function to load keys */ static int load_keys (const struct GNUNET_CONFIGURATION_Handle *c) { char *data_dir; char *idfile; uint64_t fsize; data_dir = NULL; idfile = NULL; fsize = 0; data_dir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR); GNUNET_asprintf (&idfile, "%s/testing_hostkeys.ecc", data_dir); GNUNET_free (data_dir); data_dir = NULL; if (GNUNET_OK != GNUNET_DISK_file_size (idfile, &fsize, GNUNET_YES, GNUNET_YES)) { GNUNET_free (idfile); return GNUNET_SYSERR; } if (0 != (fsize % GNUNET_TESTING_HOSTKEYFILESIZE)) { LOG (GNUNET_ERROR_TYPE_ERROR, _("Incorrect hostkey file format: %s\n"), idfile); GNUNET_free (idfile); return GNUNET_SYSERR; } hostkeys_fd = GNUNET_DISK_file_open (idfile, GNUNET_DISK_OPEN_READ, GNUNET_DISK_PERM_NONE); if (NULL == hostkeys_fd) { GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", idfile); GNUNET_free (idfile); return GNUNET_SYSERR; } GNUNET_free (idfile); idfile = NULL; hostkeys_data = GNUNET_DISK_file_map (hostkeys_fd, &hostkeys_map, GNUNET_DISK_MAP_TYPE_READ, fsize); if (NULL == hostkeys_data) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "mmap"); return GNUNET_SYSERR; } num_hostkeys = fsize / GNUNET_TESTING_HOSTKEYFILESIZE; return GNUNET_OK; }
/** * Determine our external IPv4 address and port using an external STUN server * * @param ah auto setup context */ static void test_stun (struct GNUNET_NAT_AutoHandle *ah) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Running STUN test\n"); /* Get port from the configuration */ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (ah->cfg, "transport-udp", "PORT", &port)) { port = 2086; } //Lets create the socket lsock4 = bind_v4 (); if (NULL == lsock4) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind"); next_phase(ah); return; } else { //Lets call our function now when it accepts ltask4 = GNUNET_SCHEDULER_add_read_net (NAT_SERVER_TIMEOUT, lsock4, &do_udp_read, ah); } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "STUN service listens on port %u\n", port); if (GNUNET_NO == GNUNET_NAT_stun_make_request (stun_server, stun_port, lsock4, &request_callback, NULL)) { /*An error happened*/ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "STUN error, stopping\n"); stop_stun (); next_phase (ah); } }
/** * Task called by the scheduler once we can do the TCP send * (or once we failed to connect...). * * @param cls the 'struct TcpContext' * @param tc scheduler context */ static void tcp_send (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct TcpContext *ctx = cls; if ((NULL != tc->write_ready) && (GNUNET_NETWORK_fdset_isset (tc->write_ready, ctx->s))) { if (-1 == GNUNET_NETWORK_socket_send (ctx->s, &ctx->data, sizeof (ctx->data))) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "send"); } GNUNET_NETWORK_socket_shutdown (ctx->s, SHUT_RDWR); } GNUNET_NETWORK_socket_close (ctx->s); GNUNET_free (ctx); }
static void write_data (const char *ptr, size_t msg_size) { ssize_t ret; size_t off; off = 0; while (off < msg_size) { ret = write (1, &ptr[off], msg_size - off); if (0 >= ret) { if (-1 == ret) GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "write"); quit (2); } off += ret; } }