static void bg_traffic_thread(SInfo *info) { static const int data_len = 10; char sbuffer[data_len + 1] = "dummydata_"; char rbuffer[data_len + 1]; int scount, rtotal = 0; info->setSenderThreadId(ThisThread::get_id()); for (;;) { if (!info->available()) { (void)handle_nsapi_size_or_error(__func__, rtotal); break; } sbuffer[data_len - 1] = 'A' + (rand() % 26); scount = info->socket().send(sbuffer, data_len); rtotal = recv_all(rbuffer, data_len, info); if (scount != rtotal || (strcmp(sbuffer, rbuffer) != 0)) { info->setUnavailable(); tr_err("Background received data does not match to sent data"); tr_err("Background sent: \"%s\"", sbuffer); tr_err("Background received: \"%s\"", rbuffer); } wait_ms(10); } }
static int sendreq( tr_natpmp_req_t * req ) { uint8_t buf[12]; int res; memset( buf, 0, sizeof( buf ) ); buf[0] = PMP_VERSION; buf[1] = PMP_OPCODE_ADDTCP; PMP_TOBUF16( buf + 4, req->askport ); if( req->adding ) { PMP_TOBUF16( buf + 6, req->askport ); PMP_TOBUF32( buf + 8, PMP_LIFETIME ); } res = tr_netSend( req->fd, buf, sizeof( buf ) ); if( TR_NET_CLOSE & res && EHOSTUNREACH == errno ) { res = TR_NET_BLOCK; } if( TR_NET_CLOSE & res ) { tr_err( "failed to send nat-pmp request (%s)", strerror( errno ) ); return 1; } else if( !( TR_NET_BLOCK & res ) ) { /* XXX is it all right to assume the entire thing is written? */ req->retry = tr_date() + req->delay; req->delay *= 2; } return 0; }
/** * Checks a JSON object contains only allowed keys * * @param obj JSON object * @param allowed_keys A NULL-terminated string array with the allowed keys * @param obsolete_keys A NULL-terminated string array with the obsolete_keys */ static int check_allowed_keys(json_t* obj, const char* allowed_keys[], const char* obsolete_keys[]) { /* obj is a JSON object */ const char *key = NULL; void *iter = json_object_iter(obj); const char **allowed = NULL; int found = FALSE; while(iter) { key = json_object_iter_key(iter); found = FALSE; for (allowed = allowed_keys; allowed && *allowed; allowed++) { if (strcmp(*allowed, key) == 0) { found = TRUE; break; } } for (allowed = obsolete_keys; allowed && *allowed; allowed++) { if (strcmp(*allowed, key) == 0) { tr_warning("Configuration option [%s] is obsolete!", key); found = TRUE; break; } } if (!found) { tr_err("Invalid configuration item found: %s", key); return FALSE; } iter = json_object_iter_next(obj, iter); } return TRUE; }
/* does not take responsibility for freeing RP realm */ void tr_comm_add_rp_realm(TR_COMM_TABLE *ctab, TR_COMM *comm, TR_RP_REALM *realm, unsigned int interval, json_t *provenance, struct timespec *expiry) { TALLOC_CTX *tmp_ctx=talloc_new(NULL); TR_COMM_MEMB *newmemb=tr_comm_memb_new(tmp_ctx); TR_COMM_MEMB *existing=NULL; if (newmemb==NULL) { tr_err("tr_comm_add_idp_realm: unable to allocate new membership record."); talloc_free(tmp_ctx); return; } tr_comm_memb_set_rp_realm(newmemb, realm); tr_comm_memb_set_comm(newmemb, comm); tr_comm_memb_set_interval(newmemb, interval); tr_comm_memb_set_provenance(newmemb, provenance); tr_comm_memb_set_expiry(newmemb, expiry); existing=tr_comm_table_find_rp_memb_origin(ctab, tr_rp_realm_get_id(realm), tr_comm_get_id(comm), tr_comm_memb_get_origin(newmemb)); tr_comm_add_if_shorter(ctab, existing, newmemb); /* takes newmemb out of tmp_ctx if needed */ talloc_free(tmp_ctx); }
/* note: this function can free the tr_web if its 'closing' flag is set and no tasks remain. callers must not reference their g pointer after calling this function */ static void tr_multi_socket_action( tr_web * g, int fd, int mask ) { int closed = FALSE; CURLMcode rc; dbgmsg( "check_run_count: prev_running %d, still_running %d", g->prev_running, g->still_running ); /* invoke libcurl's processing */ do { rc = curl_multi_socket_action( g->multi, fd, mask, &g->still_running ); dbgmsg( "event_cb(): fd %d, mask %d, still_running is %d", fd, mask, g->still_running ); } while( rc == CURLM_CALL_MULTI_PERFORM ); if( rc != CURLM_OK ) tr_err( "%s", curl_multi_strerror( rc ) ); remove_finished_tasks( g ); add_tasks_from_queue( g ); if( !g->still_running ) { stop_timer( g ); if( g->closing ) { web_close( g ); closed = TRUE; } } if( !closed ) restart_timer( g ); }
static void logFunc( int severity, const char * message ) { if( severity >= _EVENT_LOG_ERR ) tr_err( "%s", message ); else tr_dbg( "%s", message ); }
/** * returns 0 on success, or an errno value on failure. * errno values include ENOENT if the parent folder doesn't exist, * plus the errno values set by tr_mkdirp() and open(). */ static int TrOpenFile( int i, const char * folder, const char * torrentFile, int doWrite, int doPreallocate, uint64_t desiredFileSize ) { struct tr_openfile * file = &gFd->open[i]; int flags; char * filename; struct stat sb; int alreadyExisted; /* confirm the parent folder exists */ if( stat( folder, &sb ) || !S_ISDIR( sb.st_mode ) ) return ENOENT; /* create subfolders, if any */ filename = tr_buildPath( folder, torrentFile, NULL ); if( doWrite ) { char * tmp = tr_dirname( filename ); const int err = tr_mkdirp( tmp, 0777 ) ? errno : 0; tr_free( tmp ); if( err ) { tr_free( filename ); return err; } } alreadyExisted = !stat( filename, &sb ) && S_ISREG( sb.st_mode ); if( doWrite && !alreadyExisted && doPreallocate ) if( preallocateFile( filename, desiredFileSize ) ) tr_inf( _( "Preallocated file \"%s\"" ), filename ); /* open the file */ flags = doWrite ? ( O_RDWR | O_CREAT ) : O_RDONLY; #ifdef O_LARGEFILE flags |= O_LARGEFILE; #endif #ifdef WIN32 flags |= O_BINARY; #endif file->fd = open( filename, flags, 0666 ); if( file->fd == -1 ) { const int err = errno; tr_err( _( "Couldn't open \"%1$s\": %2$s" ), filename, tr_strerror( err ) ); tr_free( filename ); return err; } tr_free( filename ); return 0; }
/* Get a listener for tids requests, returns its socket fd. Accept * connections with tids_accept() */ nfds_t tids_get_listener(TIDS_INSTANCE *tids, TIDS_REQ_FUNC *req_handler, tids_auth_func *auth_handler, const char *hostname, int port, void *cookie, int *fd_out, size_t max_fd) { nfds_t n_fd = 0; nfds_t ii = 0; tids->tids_port = port; n_fd = tr_sock_listen_all(port, fd_out, max_fd); if (n_fd == 0) tr_err("tids_get_listener: Error opening port %d", port); else { /* opening port succeeded */ tr_info("tids_get_listener: Opened port %d.", port); /* make this socket non-blocking */ for (ii=0; ii<n_fd; ii++) { if (0 != fcntl(fd_out[ii], F_SETFL, O_NONBLOCK)) { tr_err("tids_get_listener: Error setting O_NONBLOCK."); for (ii=0; ii<n_fd; ii++) { close(fd_out[ii]); fd_out[ii]=-1; } n_fd = 0; break; } } } if (n_fd > 0) { /* store the caller's request handler & cookie */ tids->req_handler = req_handler; tids->auth_handler = auth_handler; tids->hostname = hostname; tids->cookie = cookie; } return (int)n_fd; }
/* * \brief Configure mesh network * */ void thread_tasklet_configure_and_connect_to_network(void) { int8_t status; link_configuration_s* temp_link_config=NULL; if (MBED_CONF_MBED_MESH_API_THREAD_DEVICE_TYPE == MESH_DEVICE_TYPE_THREAD_MINIMAL_END_DEVICE) { thread_tasklet_data_ptr->operating_mode = NET_6LOWPAN_HOST; } else if (MBED_CONF_MBED_MESH_API_THREAD_DEVICE_TYPE == MESH_DEVICE_TYPE_THREAD_SLEEPY_END_DEVICE) { thread_tasklet_data_ptr->operating_mode = NET_6LOWPAN_SLEEPY_HOST; } else { thread_tasklet_data_ptr->operating_mode = NET_6LOWPAN_ROUTER; } arm_nwk_interface_configure_6lowpan_bootstrap_set( thread_tasklet_data_ptr->nwk_if_id, thread_tasklet_data_ptr->operating_mode, NET_6LOWPAN_THREAD); thread_tasklet_data_ptr->channel_list.channel_page = (channel_page_e)MBED_CONF_MBED_MESH_API_THREAD_CONFIG_CHANNEL_PAGE; thread_tasklet_data_ptr->channel_list.channel_mask[0] = MBED_CONF_MBED_MESH_API_THREAD_CONFIG_CHANNEL_MASK; TRACE_DETAIL("channel page: %d", thread_tasklet_data_ptr->channel_list.channel_page); TRACE_DETAIL("channel mask: 0x%.8lx", thread_tasklet_data_ptr->channel_list.channel_mask[0]); // PSKd const char PSKd[] = MBED_CONF_MBED_MESH_API_THREAD_PSKD; MBED_ASSERT(sizeof(PSKd) > 5 && sizeof(PSKd) < 33); char *dyn_buf = ns_dyn_mem_alloc(sizeof(PSKd)); strcpy(dyn_buf, PSKd); ns_dyn_mem_free(device_configuration.PSKd_ptr); device_configuration.PSKd_ptr = (uint8_t*)dyn_buf; device_configuration.PSKd_len = sizeof(PSKd) - 1; if (true == MBED_CONF_MBED_MESH_API_THREAD_USE_STATIC_LINK_CONFIG) { read_link_configuration(); temp_link_config = &thread_tasklet_data_ptr->link_config; } thread_management_node_init(thread_tasklet_data_ptr->nwk_if_id, &thread_tasklet_data_ptr->channel_list, &device_configuration, temp_link_config); status = arm_nwk_interface_up(thread_tasklet_data_ptr->nwk_if_id); if (status >= 0) { thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_STARTED; tr_info("Start Thread bootstrap (%s mode)", thread_tasklet_data_ptr->operating_mode == NET_6LOWPAN_SLEEPY_HOST ? "SED" : "Router"); } else { thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED; tr_err("Bootstrap start failed, %d", status); thread_tasklet_network_state_changed(MESH_BOOTSTRAP_START_FAILED); } }
static void watchdir_new_impl( dtr_watchdir * w ) { int i; w->inotify_fd = inotify_init( ); tr_inf( "Using inotify to watch directory \"%s\"", w->dir ); i = inotify_add_watch( w->inotify_fd, w->dir, DTR_INOTIFY_MASK ); if( i < 0 ) tr_err( "Unable to watch \"%s\": %s", w->dir, strerror (errno) ); }
static int sendSSDP( tr_fd_t * fdlimit, int fd ) { char buf[102]; int len; struct sockaddr_in sin; if( 0 > fd ) { if( tr_fdSocketWillCreate( fdlimit, 0 ) ) { return -1; } fd = tr_netBindUDP( 0 ); if( 0 > fd ) { tr_fdSocketClosed( fdlimit, 0 ); return -1; } } tr_dbg( "sending upnp ssdp discover message" ); len = snprintf( buf, sizeof( buf ), "M-SEARCH * HTTP/1.1\r\n" "Host: %s:%i\r\n" "Man: \"ssdp:discover\"\r\n" "ST: %s\r\n" "MX: 3\r\n" "\r\n", SSDP_ADDR, SSDP_PORT, SSDP_TYPE ); /* if this assertion ever fails then just increase the size of buf */ assert( (int) sizeof( buf ) > len ); memset( &sin, 0, sizeof( sin ) ); sin.sin_family = AF_INET; sin.sin_addr.s_addr = inet_addr( SSDP_ADDR ); sin.sin_port = htons( SSDP_PORT ); if( 0 > sendto( fd, buf, len, 0, (struct sockaddr*) &sin, sizeof( sin ) ) ) { if( EAGAIN != errno ) { tr_err( "Could not send SSDP discover message (%s)", strerror( errno ) ); } killSock( fdlimit, &fd ); return -1; } return fd; }
static void blocklistLoad( tr_blocklist * b ) { int fd; struct stat st; const char * err_fmt = _( "Couldn't read \"%1$s\": %2$s" ); blocklistClose( b ); if( stat( b->filename, &st ) == -1 ) return; fd = open( b->filename, O_RDONLY ); if( fd == -1 ) { tr_err( err_fmt, b->filename, tr_strerror( errno ) ); return; } #ifndef WIN32 b->rules = mmap( NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0 ); #else b->rules = mmap( NULL, st.st_size, 0, 0, fd, 0 ); #endif if( !b->rules ) { tr_err( err_fmt, b->filename, tr_strerror( errno ) ); close( fd ); return; } b->byteCount = st.st_size; b->ruleCount = st.st_size / sizeof( struct tr_ip_range ); b->fd = fd; { char * base = tr_basename( b->filename ); tr_inf( _( "Blocklist \"%s\" contains %'zu entries" ), base, b->ruleCount ); tr_free( base ); } }
/* * \brief Configure and establish network connection * */ void nd_tasklet_configure_and_connect_to_network(void) { int8_t status; char *sec_mode; // configure bootstrap arm_nwk_interface_configure_6lowpan_bootstrap_set( tasklet_data_ptr->network_interface_id, tasklet_data_ptr->mode, NET_6LOWPAN_ND_WITH_MLE); sec_mode = STR(MBED_MESH_API_6LOWPAN_ND_SECURITY_MODE); if (strcmp(sec_mode, "PSK") == 0) { tr_debug("Using PSK security mode."); tasklet_data_ptr->sec_mode = NET_SEC_MODE_PSK_LINK_SECURITY; tasklet_data_ptr->psk_sec_info.key_id = MBED_MESH_API_6LOWPAN_ND_PSK_KEY_ID; memcpy(tasklet_data_ptr->psk_sec_info.security_key, (const uint8_t[16])MBED_MESH_API_6LOWPAN_ND_PSK_KEY, 16); } else { tr_debug("Link-layer security NOT enabled."); tasklet_data_ptr->sec_mode = NET_SEC_MODE_NO_LINK_SECURITY; } // configure link layer security arm_nwk_link_layer_security_mode( tasklet_data_ptr->network_interface_id, tasklet_data_ptr->sec_mode, MBED_MESH_API_6LOWPAN_ND_SEC_LEVEL, &tasklet_data_ptr->psk_sec_info); // configure scan parameters arm_nwk_6lowpan_link_scan_parameter_set(tasklet_data_ptr->network_interface_id, 5); // configure scan channels initialize_channel_list(); // Configure scan options (NULL disables filter) arm_nwk_6lowpan_link_nwk_id_filter_for_nwk_scan( tasklet_data_ptr->network_interface_id, NULL); arm_nwk_6lowpan_link_panid_filter_for_nwk_scan( tasklet_data_ptr->network_interface_id, MBED_MESH_API_6LOWPAN_ND_PANID_FILTER); status = arm_nwk_interface_up(tasklet_data_ptr->network_interface_id); if (status >= 0) { tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_STARTED; tr_info("Start 6LoWPAN ND Bootstrap"); } else { tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED; tr_err("Bootstrap start failed, %d", status); nd_tasklet_network_state_changed(MESH_BOOTSTRAP_START_FAILED); } }
/* * \brief A function which will be eventually called by NanoStack OS when ever the OS has an event to deliver. * @param event, describes the sender, receiver and event type. * * NOTE: Interrupts requested by HW are possible during this function! */ void thread_tasklet_main(arm_event_s *event) { arm_library_event_type_e event_type; event_type = (arm_library_event_type_e) event->event_type; switch (event_type) { case ARM_LIB_NWK_INTERFACE_EVENT: /* This event is delivered every and each time when there is new * information of network connectivity. */ thread_tasklet_parse_network_event(event); break; case ARM_LIB_TASKLET_INIT_EVENT: /* Event with type EV_INIT is an initializer event of NanoStack OS. * The event is delivered when the NanoStack OS is running fine. * This event should be delivered ONLY ONCE. */ mesh_system_send_connect_event(thread_tasklet_data_ptr->tasklet); break; case ARM_LIB_SYSTEM_TIMER_EVENT: eventOS_event_timer_cancel(event->event_id, thread_tasklet_data_ptr->tasklet); if (event->event_id == TIMER_EVENT_START_BOOTSTRAP) { int8_t status; tr_debug("Restart bootstrap"); status = arm_nwk_interface_up(thread_tasklet_data_ptr->nwk_if_id); if (status >= 0) { thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_STARTED; tr_info("Start Thread bootstrap (%s mode)", thread_tasklet_data_ptr->operating_mode == NET_6LOWPAN_SLEEPY_HOST ? "SED" : "Router"); thread_tasklet_network_state_changed(MESH_BOOTSTRAP_STARTED); } else { thread_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_FAILED; tr_err("Bootstrap start failed, %d", status); thread_tasklet_network_state_changed(MESH_BOOTSTRAP_START_FAILED); } } break; case APPLICATION_EVENT: if (event->event_id == APPL_EVENT_CONNECT) { thread_tasklet_configure_and_connect_to_network(); } break; default: break; } // switch(event_type) }
/** * Handle GSS authentication and authorization * * @param conn connection file descriptor * @param acceptor_service name of acceptor to present to initiator * @param acceptor_hostname hostname of acceptor to present to initiator * @param gssctx GSS context * @param auth_cb authorization callback * @param auth_cookie generic data to pass to the authorization callback * @return 0 on successful auth, 1 on disallowed auth, -1 on error */ static int tr_gss_auth_connection(int conn, const char *acceptor_service, const char *acceptor_hostname, gss_ctx_id_t *gssctx, TR_GSS_AUTH_FN auth_cb, void *auth_cookie) { int rc = 0; int auth, autherr = 0; gss_buffer_desc nameBuffer = {0, NULL}; TR_GSS_COOKIE *cookie = NULL; nameBuffer.value = talloc_asprintf(NULL, "%s@%s", acceptor_service, acceptor_hostname); if (nameBuffer.value == NULL) { tr_err("tr_gss_auth_connection: Error allocating acceptor name."); return -1; } nameBuffer.length = strlen(nameBuffer.value); /* Set up for the auth callback. There are two layers of callbacks here: we * use our own, which handles gsscon interfacing and calls the auth_cb parameter * to do the actual auth. Store the auth_cb information in a metacookie. */ cookie = talloc(NULL, TR_GSS_COOKIE); cookie->auth_cb=auth_cb; cookie->auth_cookie=auth_cookie; /* Now call gsscon with *our* auth callback and cookie */ tr_debug("tr_gss_auth_connection: Beginning passive authentication as %.*s", nameBuffer.length, nameBuffer.value); rc = gsscon_passive_authenticate(conn, nameBuffer, gssctx, tr_gss_auth_cb, cookie); talloc_free(cookie); talloc_free(nameBuffer.value); if (rc) { tr_debug("tr_gss_auth_connection: Error from gsscon_passive_authenticate(), rc = %d.", rc); return -1; } tr_debug("tr_gss_auth_connection: Authentication succeeded, now authorizing."); rc = gsscon_authorize(*gssctx, &auth, &autherr); if (rc) { tr_debug("tr_gss_auth_connection: Error from gsscon_authorize, rc = %d, autherr = %d.", rc, autherr); return -1; } if (auth) tr_debug("tr_gss_auth_connection: Connection authenticated, conn = %d.", conn); else tr_debug("tr_gss_auth_connection: Authentication failed, conn %d.", conn); return !auth; }
static void blocklistLoad (tr_blocklist * b) { int fd; size_t byteCount; struct stat st; const char * err_fmt = _("Couldn't read \"%1$s\": %2$s"); blocklistClose (b); if (stat (b->filename, &st) == -1) return; fd = open (b->filename, O_RDONLY | O_BINARY); if (fd == -1) { tr_err (err_fmt, b->filename, tr_strerror (errno)); return; } byteCount = (size_t) st.st_size; b->rules = mmap (NULL, byteCount, PROT_READ, MAP_PRIVATE, fd, 0); if (!b->rules) { tr_err (err_fmt, b->filename, tr_strerror (errno)); close (fd); return; } b->fd = fd; b->byteCount = byteCount; b->ruleCount = byteCount / sizeof (struct tr_ipv4_range); { char * base = tr_basename (b->filename); tr_inf (_("Blocklist \"%s\" contains %zu entries"), base, b->ruleCount); tr_free (base); } }
int tr_jsonParse( const void * vbuf, size_t len, tr_benc * setme_benc, const uint8_t ** setme_end ) { int line = 1; int column = 1; int err = 0; const unsigned char * buf = vbuf; const void * bufend = buf + len; struct JSON_config_struct config; struct JSON_parser_struct * checker; struct json_benc_data data; init_JSON_config( &config ); config.callback = callback; config.callback_ctx = &data; config.depth = -1; data.hasContent = FALSE; data.key = NULL; data.top = setme_benc; data.stack = TR_PTR_ARRAY_INIT; checker = new_JSON_parser( &config ); while( ( buf != bufend ) && JSON_parser_char( checker, *buf ) ) { if( *buf != '\n' ) ++column; else { ++line; column = 1; } ++buf; } if( buf != bufend ) { tr_err( "JSON parser failed at line %d, column %d: \"%.16s\"", line, column, buf ); err = EILSEQ; } if( !data.hasContent ) err = EINVAL; if( setme_end ) *setme_end = (const uint8_t*) buf; delete_JSON_parser( checker ); tr_ptrArrayDestruct( &data.stack, NULL ); return err; }
static void onFileAdded( tr_session * session, const char * dir, const char * file ) { char * filename = tr_buildPath( dir, file, NULL ); tr_ctor * ctor = tr_ctorNew( session ); int err = tr_ctorSetMetainfoFromFile( ctor, filename ); if( !err ) { tr_torrentNew( ctor, &err ); if( err == TR_PARSE_ERR ) tr_err( "Error parsing .torrent file \"%s\"", file ); else { tr_bool trash = FALSE; int test = tr_ctorGetDeleteSource( ctor, &trash ); tr_inf( "Parsing .torrent file successful \"%s\"", file ); if( !test && trash ) { tr_inf( "Deleting input .torrent file \"%s\"", file ); if( remove( filename ) ) tr_err( "Error deleting .torrent file: %s", tr_strerror( errno ) ); } else { char * new_filename = tr_strdup_printf( "%s.added", filename ); rename( filename, new_filename ); tr_free( new_filename ); } } } tr_ctorFree( ctor ); tr_free( filename ); }
static buffer_t *udp_checksum_check(buffer_t *buf) { uint8_t *ptr = buffer_data_pointer(buf) + 6; uint16_t check = common_read_16_bit(ptr); // We refuse checksum field 0000, as per IPv6 (RFC 2460). Would have // to accept this if handling IPv4. if (check == 0 || buffer_ipv6_fcf(buf, IPV6_NH_UDP)) { tr_err("CKSUM ERROR - src=%s", trace_ipv6(buf->src_sa.address)); protocol_stats_update(STATS_IP_CKSUM_ERROR, 1); buf = buffer_free(buf); } return buf; }
static void mcastpulse( tr_natpmp_t * pmp ) { struct sockaddr_in sin; uint8_t buf[16]; int res; char dbgstr[INET_ADDRSTRLEN]; tr_natpmp_parse_t parse; res = tr_netRecvFrom( pmp->mcastfd, buf, sizeof( buf ), &sin ); if( TR_NET_BLOCK & res ) { return; } else if( TR_NET_CLOSE & res ) { tr_err( "error reading nat-pmp multicast message" ); killsock( &pmp->mcastfd ); return; } tr_netNtop( &sin.sin_addr, dbgstr, sizeof( dbgstr ) ); tr_dbg( "nat-pmp read %i byte multicast packet from %s", res, dbgstr ); if( pmp->dest.s_addr != sin.sin_addr.s_addr ) { tr_dbg( "nat-pmp ignoring multicast packet from unknown host %s", dbgstr ); return; } if( TR_NET_OK == parseresponse( buf, res, -1, &parse ) ) { if( checktime( &pmp->uptime, parse.seconds ) ) { pmp->renew = 0; tr_inf( "detected nat-pmp device reset" ); if( NULL != pmp->req ) { resetreq( pmp->req ); } } if( PMP_STATE_NOBODYHOME == pmp->state ) { tr_dbg( "nat-pmp state notfound -> idle" ); pmp->state = PMP_STATE_IDLE; } } }
int tr_getDefaultRoute( struct in_addr * addr ) { struct netif *netif = NULL; netif = netif_find("en0"); if (netif == NULL) { tr_err("Can not find netif named <en>!\n"); return -1; } addr->s_addr = netif->gw.addr; return 0; }
/** * Produces a JSON-encoded msg containing the TID response * * @param mem_ctx talloc context for the return value * @param resp outgoing response * @return JSON-encoded message containing the TID response */ static char *tids_encode_response(TALLOC_CTX *mem_ctx, TID_RESP *resp) { TR_MSG mresp; char *resp_buf = NULL; /* Construct the response message */ tid_set_tr_msg_resp(&mresp, resp); /* Encode the message to JSON */ resp_buf = tr_msg_encode(mem_ctx, &mresp); if (resp_buf == NULL) { tr_err("tids_encode_response: Error encoding json response."); return NULL; } tr_debug("tids_encode_response: Encoded response: %s", resp_buf); /* Success */ return resp_buf; }
/** * Encode/send a response * * Part of the public interface * * @param tids not actually used, but kept for ABI compatibility * @param req * @param resp * @return */ int tids_send_response (TIDS_INSTANCE *tids, TID_REQ *req, TID_RESP *resp) { int err; char *resp_buf; if ((!tids) || (!req) || (!resp)) { tr_debug("tids_send_response: Invalid parameters."); return -1; } /* Never send a second response if we already sent one. */ if (req->resp_sent) return 0; resp_buf = tids_encode_response(NULL, NULL); if (resp_buf == NULL) { tr_err("tids_send_response: Error encoding json response."); tr_audit_req(req); return -1; } tr_debug("tids_send_response: Encoded response: %s", resp_buf); /* If external logging is enabled, fire off a message */ /* TODO Can be moved to end once segfault in gsscon_write_encrypted_token fixed */ tr_audit_resp(resp); /* Send the response over the connection */ err = gsscon_write_encrypted_token (req->conn, req->gssctx, resp_buf, strlen(resp_buf) + 1); if (err) { tr_notice("tids_send_response: Error sending response over connection."); tr_audit_req(req); return -1; } /* indicate that a response has been sent for this request */ req->resp_sent = 1; free(resp_buf); return 0; }
/** * Process to handle an incoming TIDS request * * This should be run in the child process after a fork(). Handles * the request, writes the result to result_fd, and terminates. * Never returns to the caller. * * @param tids TID server instance * @param conn_fd file descriptor for the incoming connection * @param result_fd writable file descriptor for the result, or 0 to disable reporting */ static void tids_handle_proc(TIDS_INSTANCE *tids, int conn_fd, int result_fd) { const char *response_message = NULL; struct rlimit rlim; /* for disabling core dump */ switch(tr_gss_handle_connection(conn_fd, "trustidentity", tids->hostname, /* acceptor name */ tids->auth_handler, tids->cookie, /* auth callback and cookie */ tids_req_cb, tids /* req callback and cookie */ )) { case TR_GSS_SUCCESS: response_message = TIDS_SUCCESS_MESSAGE; break; case TR_GSS_REQUEST_FAILED: response_message = TIDS_ERROR_MESSAGE; break; case TR_GSS_INTERNAL_ERROR: case TR_GSS_ERROR: default: response_message = TIDS_REQ_FAIL_MESSAGE; break; } if (0 != result_fd) { /* write strlen + 1 to include the null termination */ if (write(result_fd, response_message, strlen(response_message) + 1) < 0) tr_err("tids_accept: child process unable to write to pipe"); } close(result_fd); close(conn_fd); /* This ought to be an exit(0), but log4shib does not play well with fork() due to * threading issues. To ensure we do not get stuck in the exit handler, we will * abort. First disable core dump for this subprocess (the main process will still * dump core if the environment allows). */ rlim.rlim_cur = 0; /* max core size of 0 */ rlim.rlim_max = 0; /* prevent the core size limit from being raised later */ setrlimit(RLIMIT_CORE, &rlim); abort(); /* exit hard */ }
int tr_fdSocketCreate( int type ) { int s = -1; tr_lockLock( gFd->lock ); if( gFd->socketCount < getSocketMax( gFd ) ) if( ( s = socket( AF_INET, type, 0 ) ) < 0 ) tr_err( _( "Couldn't create socket: %s" ), tr_strerror( sockerrno ) ); if( s > -1 ) ++gFd->socketCount; assert( gFd->socketCount >= 0 ); tr_lockUnlock( gFd->lock ); return s; }
static void add_tasks_from_queue( tr_web * g ) { while( ( g->still_running < MAX_CONCURRENT_TASKS ) && ( tr_list_size( g->easy_queue ) > 0 ) ) { CURL * easy = tr_list_pop_front( &g->easy_queue ); if( easy ) { const CURLMcode rc = curl_multi_add_handle( g->multi, easy ); if( rc != CURLM_OK ) tr_err( "%s", curl_multi_strerror( rc ) ); else { dbgmsg( "pumped the task queue, %d remain", tr_list_size( g->easy_queue ) ); ++g->still_running; } } } }
int tr_fdSocketCreate( tr_session * session, int domain, int type ) { int s = -1; struct tr_fdInfo * gFd; assert( tr_isSession( session ) ); assert( session->fdInfo != NULL ); gFd = session->fdInfo; if( gFd->socketCount < gFd->socketLimit ) if( ( s = socket( domain, type, 0 ) ) < 0 ) { if( sockerrno != EAFNOSUPPORT ) tr_err( _( "Couldn't create socket: %s" ), tr_strerror( sockerrno ) ); } if( s > -1 ) ++gFd->socketCount; assert( gFd->socketCount >= 0 ); if( s >= 0 ) { static tr_bool buf_logged = FALSE; if( !buf_logged ) { int i; socklen_t size = sizeof( int ); buf_logged = TRUE; getsockopt( s, SOL_SOCKET, SO_SNDBUF, &i, &size ); tr_dbg( "SO_SNDBUF size is %d", i ); getsockopt( s, SOL_SOCKET, SO_RCVBUF, &i, &size ); tr_dbg( "SO_RCVBUF size is %d", i ); } } return s; }
static void watchdir_new_impl (dtr_watchdir * w) { int i; DIR * odir; w->inotify_fd = inotify_init (); if (w->inotify_fd < 0) { i = -1; } else { tr_inf ("Using inotify to watch directory \"%s\"", w->dir); i = inotify_add_watch (w->inotify_fd, w->dir, DTR_INOTIFY_MASK); } if (i < 0) { tr_err ("Unable to watch \"%s\": %s", w->dir, tr_strerror (errno)); } else if ((odir = opendir (w->dir))) { struct dirent * d; while ((d = readdir (odir))) { const char * name = d->d_name; if (!tr_str_has_suffix (name, ".torrent")) /* skip non-torrents */ continue; tr_inf ("Found new .torrent file \"%s\" in watchdir \"%s\"", name, w->dir); w->callback (w->session, w->dir, name); } closedir (odir); } }
static tr_tristate_t recvSSDP( int fd, char * buf, int * len ) { if( 0 > fd ) { return TR_ERROR; } *len = tr_netRecv( fd, ( uint8_t * ) buf, *len ); if( TR_NET_BLOCK & *len ) { return TR_WAIT; } else if( TR_NET_CLOSE & *len ) { tr_err( "Could not receive SSDP message (%s)", strerror( errno ) ); return TR_ERROR; } else { return TR_OK; } }
int tidc_send_request (TIDC_INSTANCE *tidc, int conn, gss_ctx_id_t gssctx, const char *rp_realm, const char *realm, const char *comm, TIDC_RESP_FUNC *resp_handler, void *cookie) { TID_REQ *tid_req = NULL; int rc; /* Create and populate a TID req structure */ if (!(tid_req = tid_req_new())) return -1; tid_req->conn = conn; tid_req->gssctx = gssctx; if ((NULL == (tid_req->rp_realm = tr_new_name(rp_realm))) || (NULL == (tid_req->realm = tr_new_name(realm))) || (NULL == (tid_req->comm = tr_new_name(comm)))) { tr_err ( "tidc_send_request: Error duplicating names.\n"); goto error; } tid_req->tidc_dh = tr_dh_dup(tidc->client_dh); rc = tidc_fwd_request(tidc, tid_req, resp_handler, cookie); goto cleanup; error: rc = -1; cleanup: tid_req_free(tid_req); return rc; }