/** * Run "upnpc -r" to map our internal port. * * @param mini our handle */ static void run_upnpc_r (struct GNUNET_NAT_MiniHandle *mini) { char pstr[6]; GNUNET_snprintf (pstr, sizeof (pstr), "%u", (unsigned int) mini->port); mini->map_cmd = GNUNET_OS_command_run (&process_map_output, mini, MAP_TIMEOUT, "upnpc", "upnpc", "-r", pstr, mini->is_tcp ? "tcp" : "udp", NULL); if (NULL == mini->map_cmd) { mini->ac (mini->ac_cls, GNUNET_SYSERR, NULL, 0, GNUNET_NAT_ERROR_UPNPC_FAILED); return; } }
/** * Remove a mapping created with (mini)upnpc. Calling * this function will give 'upnpc' 1s to remove tha mapping, * so while this function is non-blocking, a task will be * left with the scheduler for up to 1s past this call. * * @param mini the handle */ void GNUNET_NAT_mini_map_stop (struct GNUNET_NAT_MiniHandle *mini) { char pstr[6]; if (NULL != mini->refresh_task) { GNUNET_SCHEDULER_cancel (mini->refresh_task); mini->refresh_task = NULL; } if (NULL != mini->refresh_cmd) { GNUNET_OS_command_stop (mini->refresh_cmd); mini->refresh_cmd = NULL; } if (NULL != mini->map_cmd) { GNUNET_OS_command_stop (mini->map_cmd); mini->map_cmd = NULL; } if (GNUNET_NO == mini->did_map) { GNUNET_free (mini); return; } mini->ac (mini->ac_cls, GNUNET_NO, (const struct sockaddr *) &mini->current_addr, sizeof (mini->current_addr), GNUNET_NAT_ERROR_SUCCESS); /* Note: oddly enough, deletion uses the external port whereas * addition uses the internal port; this rarely matters since they * often are the same, but it might... */ GNUNET_snprintf (pstr, sizeof (pstr), "%u", (unsigned int) ntohs (mini->current_addr.sin_port)); LOG (GNUNET_ERROR_TYPE_DEBUG, "Unmapping port %u with UPnP\n", ntohs (mini->current_addr.sin_port)); mini->unmap_cmd = GNUNET_OS_command_run (&process_unmap_output, mini, UNMAP_TIMEOUT, "upnpc", "upnpc", "-d", pstr, mini->is_tcp ? "tcp" : "udp", NULL); }
/** * Run "upnpc -l" to find out if our mapping changed. * * @param cls the 'struct GNUNET_NAT_MiniHandle' */ static void do_refresh (void *cls) { struct GNUNET_NAT_MiniHandle *mini = cls; int ac; mini->refresh_task = GNUNET_SCHEDULER_add_delayed (MAP_REFRESH_FREQ, &do_refresh, mini); LOG (GNUNET_ERROR_TYPE_DEBUG, "Running `upnpc' to check if our mapping still exists\n"); mini->found = GNUNET_NO; ac = GNUNET_NO; if (NULL != mini->map_cmd) { /* took way too long, abort it! */ GNUNET_OS_command_stop (mini->map_cmd); mini->map_cmd = NULL; ac = GNUNET_YES; } if (NULL != mini->refresh_cmd) { /* took way too long, abort it! */ GNUNET_OS_command_stop (mini->refresh_cmd); mini->refresh_cmd = NULL; ac = GNUNET_YES; } mini->refresh_cmd = GNUNET_OS_command_run (&process_refresh_output, mini, MAP_TIMEOUT, "upnpc", "upnpc", "-l", NULL); if (GNUNET_YES == ac) mini->ac (mini->ac_cls, GNUNET_SYSERR, NULL, 0, GNUNET_NAT_ERROR_UPNPC_TIMEOUT); }
static void exec_cmd (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct SysmonProperty *sp = cls; GNUNET_assert (NULL != sp->cmd); if (NULL != sp->cmd_exec_handle) { GNUNET_OS_command_stop (sp->cmd_exec_handle); sp->cmd_exec_handle = NULL; GNUNET_break (0); } GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Property `%s': command `%s' `%s'\n", sp->desc, sp->cmd, sp->cmd_args); if (NULL == (sp->cmd_exec_handle = GNUNET_OS_command_run (&exec_cmd_proc, sp, GNUNET_TIME_UNIT_SECONDS, sp->cmd, sp->cmd, sp->cmd_args, NULL))) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Property `%s': command `%s' failed\n", sp->desc, sp->cmd); }