void servtest(void) { int servfd, clifd; /* server and client fd's */ struct sockaddr_in serv_addr, cli_addr; int clilen, servlen; char buf[BUFSIZE]; int msgcount=0; struct iovec iov[2]; printf("server started...\n"); /* create a server socket */ if ((servfd=socket(AF_INET,SOCK_STREAM,0)) < 0) { err_sys("server socket"); } /* bind our local address so */ memset(&serv_addr,0,sizeof(serv_addr)); serv_addr.sin_family=AF_INET; serv_addr.sin_addr.s_addr=htonl(INADDR_ANY); serv_addr.sin_port=0; if (bind(servfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) { err_sys("server bind"); } /* find out which port we actually bound to */ servlen=sizeof(serv_addr); if (getsockname(servfd,(struct sockaddr *) &serv_addr, &servlen) < 0) { err_sys("getsockname"); } serv_port=ntohs(serv_addr.sin_port); printf("server started: bound to local address: %s\n", str_addr(&serv_addr)); listen(servfd,5); while (1) { clilen=sizeof(cli_addr); if ((clifd=accept(servfd,(struct sockaddr *) &cli_addr, &clilen)) < 0) { err_sys("accept"); } printf("server accepted connection from: %s\n", str_addr(&cli_addr)); while (1) { sprintf(buf,"this is message %d",msgcount++); printf("server sending message: [%s]\n",buf); if (write(clifd,buf,strlen(buf)+1) < 0) { printf("server: write() failed, closing connection...\n"); close(clifd); break; } sleep(1); } } }
int net_bind( const char name[], const char addr[], const char port[], const char ifname[], int protocol, int af ) { char addrbuf[FULL_ADDSTRLEN+1]; const int opt_on = 1; int sock; socklen_t addrlen; IP sockaddr; if( addr_parse( &sockaddr, addr, port, af ) != 0 ) { log_err( "%s: Failed to parse IP address '%s' and port '%s'.", name, addr, port ); return -1; } if( (sock = net_socket( name, ifname, protocol, sockaddr.ss_family )) < 0 ) { return -1; } if( sockaddr.ss_family == AF_INET6 ) { if( setsockopt( sock, IPPROTO_IPV6, IPV6_V6ONLY, &opt_on, sizeof(opt_on) ) < 0 ) { close( sock ); log_err( "%s: Failed to set socket option IPV6_V6ONLY: '%s' (%s)", name, strerror( errno ), str_addr( &sockaddr, addrbuf ) ); return -1; } } addrlen = addr_len( &sockaddr ); if( bind( sock, (struct sockaddr*) &sockaddr, addrlen ) < 0 ) { close( sock ); log_err( "%s: Failed to bind socket to address: '%s' (%s)", name, strerror( errno ), str_addr( &sockaddr, addrbuf ) ); return -1; } if( protocol == IPPROTO_TCP && listen( sock, 5 ) < 0 ) { close( sock ); log_err( "%s: Failed to listen on socket: '%s' (%s)", name, strerror( errno ), str_addr( &sockaddr, addrbuf ) ); return -1; } log_info( ifname ? "%s: Bind to %s, interface %s" : "%s: Bind to %s", name, str_addr( &sockaddr, addrbuf ), ifname ); return sock; }
static void plainprpl_get_info(PurpleConnection *gc, const char *buddy_name) { PurpleBuddy *buddy; plain_buddy_state *bstate; PurpleNotifyUserInfo *info; const char *addr_str; buddy = purple_find_buddy(gc->account, buddy_name); bstate = purple_buddy_get_protocol_data(buddy); info = purple_notify_user_info_new(); if (bstate) { PurplePresence *presence = purple_buddy_get_presence(buddy); PurpleStatus *status = purple_presence_get_active_status(presence); const char *status_name = purple_status_get_name(status); purple_notify_user_info_add_pair(info, "Status", status_name); addr_str = purple_blist_node_get_string(PURPLE_BLIST_NODE(buddy), "addr_str"); purple_notify_user_info_add_pair(info, "Address", addr_str); if (bstate->state == BUDDY_STATE_RESOLVE) { /* The IP address has not been resolved yet */ purple_notify_user_info_add_pair(info, "Resolved", "Unknown"); } else { purple_notify_user_info_add_pair(info, "Resolved", str_addr(&bstate->addr)); } purple_notify_user_info_add_pair(info, "Last Seen", str_time(bstate->time_recv)); } else { purple_notify_user_info_add_pair(info, "Info", "Missing Data"); } /* Show a buddy's user info in a nice dialog box */ purple_notify_userinfo(gc, buddy_name, info, NULL, NULL); }
/* Print announced ids we have received */ void kad_debug_storage( int fd ) { char addrbuf[FULL_ADDSTRLEN+1]; char hexbuf[SHA1_HEX_LENGTH+1]; struct storage *s = storage; IP addr; int i, j; dht_lock(); for( j = 0; s != NULL; ++j ) { dprintf( fd, "Id: %s\n", str_id(s->id, hexbuf )); for( i = 0; i < s->numpeers; ++i ) { struct peer* p = &s->peers[i]; if( p->len == 16 ) { IP6 *a = (IP6 *) &addr; a->sin6_family = AF_INET6; a->sin6_port = htons( p->port ); memcpy( &a->sin6_addr, p->ip, 16 ); } else { IP4 *a = (IP4 *) &addr; a->sin_family = AF_INET; a->sin_port = htons( p->port ); memcpy( &a->sin_addr, p->ip, 4 ); } dprintf( fd, " Peer: %s\n", str_addr( &addr, addrbuf) ); } dprintf( fd, " Found %d peers.\n", i ); s = s->next; } dprintf( fd, " Found %d stored hashes from received announcements.\n", j ); dht_unlock(); }
/* Print searches */ void kad_debug_searches( int fd ) { char addrbuf[FULL_ADDSTRLEN+1]; char hexbuf[SHA1_HEX_LENGTH+1]; struct search *s = searches; int i, j; dht_lock(); for( j = 0; s != NULL; ++j ) { dprintf( fd, " Search: %s\n", str_id( s->id, hexbuf ) ); dprintf( fd, " af: %s\n", (s->af == AF_INET) ? "AF_INET" : "AF_INET6" ); dprintf( fd, " port: %hu\n", s->port ); dprintf( fd, " done: %d\n", s->done ); for(i = 0; i < s->numnodes; ++i) { struct search_node *sn = &s->nodes[i]; dprintf( fd, " Node: %s\n", str_id(sn->id, hexbuf ) ); dprintf( fd, " addr: %s\n", str_addr( &sn->ss, addrbuf ) ); dprintf( fd, " pinged: %d\n", sn->pinged ); dprintf( fd, " replied: %d\n", sn->replied ); dprintf( fd, " acked: %d\n", sn->acked ); } dprintf( fd, " Found %d nodes.\n", i ); s = s->next; } dprintf( fd, " Found %d searches.\n", j ); dht_unlock(); }
/* Print buckets (leaf/finger table) */ void kad_debug_buckets( int fd ) { char addrbuf[FULL_ADDSTRLEN+1]; char hexbuf[SHA1_HEX_LENGTH+1]; struct bucket *b; struct node *n; int i, j; dht_lock(); b = (gconf->af == AF_INET) ? buckets : buckets6; for( j = 0; b != NULL; ++j ) { dprintf( fd, " Bucket: %s\n", str_id( b->first, hexbuf ) ); n = b->nodes; for( i = 0; n != NULL; ++i ) { dprintf( fd, " Node: %s\n", str_id( n->id, hexbuf ) ); dprintf( fd, " addr: %s\n", str_addr( &n->ss, addrbuf ) ); dprintf( fd, " pinged: %d\n", n->pinged ); n = n->next; } dprintf( fd, " Found %d nodes.\n", i ); b = b->next; } dprintf( fd, " Found %d buckets.\n", j ); dht_unlock(); }
/* Print announced ids we have received */ void kad_debug_storage( int fd ) { char addrbuf[FULL_ADDSTRLEN+1]; char hexbuf[SHA1_HEX_LENGTH+1]; struct storage *s; struct peer* p; IP addr; int i, j; dht_lock(); s = storage; for( j = 0; s != NULL; ++j ) { dprintf( fd, " ID: %s\n", str_id(s->id, hexbuf )); for( i = 0; i < s->numpeers; ++i ) { p = &s->peers[i]; to_addr( &addr, &p->ip, p->len, htons( p->port ) ); dprintf( fd, " Peer: %s\n", str_addr( &addr, addrbuf) ); } dprintf( fd, " Found %d peers.\n", i ); s = s->next; } dprintf( fd, " Found %d stored hashes from received announcements.\n", j ); dht_unlock(); }
int cmd_import( REPLY *r, const char *addr_str) { char addrbuf[FULL_ADDSTRLEN+1]; IP addr; int rc; /* If the address contains no port - use the default port */ if( (rc = addr_parse_full( &addr, addr_str, DHT_PORT, gconf->af )) == ADDR_PARSE_SUCCESS ) { if( kad_ping( &addr ) == 0 ) { r_printf( r, "Send ping to: %s\n", str_addr( &addr, addrbuf ) ); return 0; } else { r_printf( r, "Failed to send ping.\n" ); return 1; } } else if( rc == ADDR_PARSE_CANNOT_RESOLVE ) { r_printf( r, "Failed to resolve address.\n" ); return 1; } else if( rc == ADDR_PARSE_NO_ADDR_FOUND ) { r_printf( r, "Failed to aquire address of required protocol.\n" ); return 1; } else { r_printf( r, "Failed to parse address.\n" ); return 1; } }
/* Send a message to a buddy */ int send_msg(plain_plugin_state *plugin_data, plain_buddy_state *buddy_data, const char *msg_str) { int rc; int sockfd = plugin_data->sockfd; IP *addr = &buddy_data->addr; const int msg_len = strlen(msg_str); int str_len = msg_len; const char *str_ptr = msg_str; /* purple_debug_info("plainprpl", "Try to send %d Bytes to: %s\n", msg_len, str_addr(addr, addrbuf)); rc = sendto( sockfd, msg_str, msg_len, 0, (struct sockaddr *)addr, sizeof(IP)); printf("rc of sendto: %d\n", rc); */ purple_debug_info("plainprpl", "Try to send %d Bytes to: %s\n", msg_len, str_addr(addr)); while (str_len > 0) { int size = (str_len < MAX_MESSAGE_SIZE) ? str_len : MAX_MESSAGE_SIZE; purple_debug_info("plainprpl", "Send (%d Bytes): %.*s\n", size, size, str_ptr); rc = sendto(sockfd, str_ptr, size, 0, (struct sockaddr *)addr, sizeof(IP)); if(rc < 0) { purple_debug_info("plainprpl", "Failed to send message: %s (%d)\n", strerror(errno), rc); return -1; } str_len -= size; str_ptr += size; } return 1; }
int mcast_send_packet( const char msg[], IP *src_addr, const char ifname[] ) { char addrbuf[FULL_ADDSTRLEN+1]; int sock; IP addr; /* Copy address to separate field and set port */ memcpy( &addr, src_addr, addr_len( (IP*) src_addr ) ); port_set( &addr, addr_port(&g_lpd_addr) ); /* For IPv6, only send from link local addresses */ if( addr.ss_family == AF_INET6) { unsigned char* a = &((IP6*) &addr)->sin6_addr.s6_addr[0]; if( !(a[0] == 0xFE && a[1] == 0x80) ) { return 1; } } if( (sock = socket( gconf->af, SOCK_DGRAM, IPPROTO_UDP )) < 0 ) { log_warn( "LPD: Cannot create send socket: %s", strerror( errno ) ); goto skip; } const int opt_on = 1; if( setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, &opt_on, sizeof(opt_on) ) < 0 ) { log_warn( "LPD: Unable to set SO_REUSEADDR: %s", strerror( errno ) ); goto skip; } if( bind( sock, (struct sockaddr*) &addr, addr_len( &addr ) ) < 0 ) { log_warn( "LPD: Cannot bind send socket: %s", strerror( errno ) ); goto skip; } if( sendto( sock, msg, strlen( msg ), 0, (struct sockaddr*) &g_lpd_addr, addr_len( &g_lpd_addr ) ) < 0 ) { log_warn( "LPD: Cannot send message from '%s': %s", str_addr( &addr, addrbuf ), strerror( errno ) ); goto skip; } log_debug( "LPD: Send peer discovery packet from source address: %s", str_addr( src_addr, addrbuf ) ); skip: close(sock); return 0; }
int cmd_blacklist( REPLY *r, const char *addr_str ) { char addrbuf[FULL_ADDSTRLEN+1]; IP addr; if( addr_parse( &addr, addr_str, NULL, gconf->af ) != 0 ) { r_printf( r, "Invalid address.\n" ); return 1; } else { kad_blacklist( &addr ); r_printf( r, "Added to blacklist: %s\n", str_addr( &addr, addrbuf ) ); return 0; } }
/* handle 'GET /lookup?foo.p2p' */ void handle_lookup( char *reply_buf, const char *params ) { char addrbuf[FULL_ADDSTRLEN+1]; IP addrs[MAX_ADDRS]; size_t num; size_t i, n; /* Lookup id - starts search when not already done */ num = N_ELEMS(addrs); if( kad_lookup_value( params, addrs, &num ) >= 0 && num > 0 ) { for( n = 0, i = 0; i < num; i++ ) { n += sprintf( reply_buf + n, "%s\n", str_addr( &addrs[i], addrbuf ) ); } } }
void kad_debug_blacklist( int fd ) { char addrbuf[FULL_ADDSTRLEN+1]; int i; dht_lock(); for( i = 0; i < (next_blacklisted % DHT_MAX_BLACKLISTED); i++ ) { dprintf( fd, " %s\n", str_addr( &blacklist[i], addrbuf ) ); } dprintf( fd, " Found %d blacklisted addresses.\n", i ); dht_unlock(); }
dnet_addr parse_addr(const std::string& addr) { dnet_addr ret; int port, family; memset(&ret, 0, sizeof(ret)); ret.addr_len = sizeof(ret.addr); std::string str_addr(addr); int err = dnet_parse_addr(const_cast<char *>(str_addr.c_str()), &port, &family); if (err) { std::cerr << "Wrong remote addr: " << addr << "\n" << std::endl; exit(1); } ret.family = family; dnet_fill_addr(&ret, const_cast<char *>(str_addr.c_str()), port, SOCK_STREAM, IPPROTO_TCP); return ret; }
JSON *string_type_parse(){ char *op = str_addr(); op++; next_char(); while (str_value() != '"'){ assert(is_end()==0); next_char(); } set_char(0); JSON *obj = CreateString(op); set_char('"'); next_char(); //puts(s); return obj; }
/* * Lookup in values we announce ourselves. * Useful for networks of only one node, also faster. */ void kad_lookup_local_values( struct results_t *results ) { char addrbuf[FULL_ADDSTRLEN+1]; struct value_t* value; IP addr; /* 127.0.0.1 */ unsigned int inaddr_loopback = htonl( INADDR_LOOPBACK ); value = values_find( results->id ); if( value ) { if( gconf->af == AF_INET6 ) { to_addr( &addr, &in6addr_loopback, 16, htons( value->port ) ); // ::1 } else { to_addr( &addr, &inaddr_loopback, 4, htons( value->port ) ); // 127.0.0.1 } log_debug( "KAD: Address found in local values: %s\n", str_addr( &addr, addrbuf ) ); results_add_addr( results, &addr ); } }
/* Export up to 32 peer addresses - more would not fit into one UDP packet */ int cmd_export( REPLY *r ) { char addrbuf[FULL_ADDSTRLEN+1]; IP addr_array[32]; size_t addr_num; size_t i; addr_num = N_ELEMS(addr_array); if( kad_export_nodes( addr_array, &addr_num ) != 0 ) { return 1; } for( i = 0; i < addr_num; ++i ) { r_printf( r, "%s\n", str_addr( &addr_array[i], addrbuf ) ); } if( i == 0 ) { r_printf( r, "No good nodes found.\n" ); return 1; } return 0; }
char *str_addr4( const IP4 *addr, char addrbuf[] ) { return str_addr( (const IP *)addr, addrbuf ); }
static gboolean plain_receive(gpointer data) { purple_debug_info("plainprpl", "plain_receive called\n"); char msgbuf[MAX_MESSAGE_SIZE]; int msgbuf_len; IP addr; const char *status; PurpleConnection *gc; PurpleAccount *account; PurpleBuddy *buddy; plain_plugin_state *pstate; plain_buddy_state *bstate; /* Get time in seconds since 1970 */ time_t now = time(NULL); gc = (PurpleConnection *) data; account = purple_connection_get_account(gc); pstate = purple_connection_get_protocol_data(gc); /* Check if we need to ping any buddy */ ping_buddies(gc, now); msgbuf_len = sizeof(msgbuf); buddy = receive_msg(pstate, &addr, msgbuf, &msgbuf_len); /* Nothing to receive or error */ if (msgbuf_len <= 0) { return TRUE; } if (!g_utf8_validate(msgbuf, -1, NULL)) { purple_debug_info("plainprpl", "Received invalid UTF8 message from %s - ignore.\n", str_addr(&addr)); return TRUE; } /* We got a message and identified the sender */ purple_debug_info("plainprpl", "Received message from %s (%d Bytes): %s\n", str_addr(&addr), strlen(msgbuf), msgbuf); /* We got a message from a source we don't know */ gboolean allow_unknown = purple_account_get_bool(account, "allow_unknown", FALSE); if (buddy == NULL) { purple_debug_info("plainprpl", "Packet from unknown buddy from address %s.\n", str_addr(&addr)); if (allow_unknown && !pstate->block_unknown) { //temporary disable the setting pstate->block_unknown = TRUE; plainprpl_add_buddy_by_contact_request(gc, str_addr(&addr), msgbuf); } return TRUE; } bstate = purple_buddy_get_protocol_data(buddy); if (bstate == NULL) { purple_debug_info("plainprpl", "bstate of buddy %s is NULL.\n", buddy->name); return TRUE; } status = PLAIN_STATUS_ONLINE; if (strcmp(msgbuf, "/ping") == 0) { /* Received a ping from a buddy */ if ((bstate->time_recv + 5) < now) { /* Send pong at most every 5 seconds */ send_msg(pstate, bstate, "/pong"); } else { /* Ignore ping */ } } else if (strcmp(msgbuf, "/pong") == 0) { /* Nothing to do */ } else if (strcmp(msgbuf, "/bye") == 0) { status = PLAIN_STATUS_OFFLINE; } else if (msgbuf[0] != '/') { /* Display message */ serv_got_im(gc, bstate->name, msgbuf, PURPLE_MESSAGE_RECV, now); } else { /* Unknown command - ignore */ } bstate->time_recv = now; /* Set buddy status to online */ purple_prpl_got_user_status(account, bstate->name, status, NULL); return TRUE; //continue loop }
/* Ping buddies a ping every 5 minutes if there is no traffic */ void ping_buddies(PurpleConnection *gc, time_t now) { PurpleBuddy *buddy; PurpleAccount *account; plain_buddy_state *bstate; plain_plugin_state *pstate; time_t time_next; GSList *iter; account = purple_connection_get_account(gc); pstate = purple_connection_get_protocol_data(gc); if(pstate->time_next > now) { return; } time_next = now + (60*5); //max time we wait for another round const char *on_lookup = purple_account_get_string(account, "on_lookup", NULL); iter = pstate->all_buddies; while (iter) { buddy = iter->data; bstate = purple_buddy_get_protocol_data(buddy); //uninitialized buddy if(bstate == NULL) { purple_debug_info("plainprpl", "Buddy %s has no state set.\n", buddy->name); goto next; } //printf("Do ping_buddies for %s\n", buddy->name); int state = bstate->state; int state_step = bstate->state_step; time_t state_next = bstate->state_next; if(state == BUDDY_STATE_RESOLVE) { const char *addr_str = purple_blist_node_get_string(PURPLE_BLIST_NODE(buddy), "addr_str"); if(exec_process(on_lookup, addr_str, on_lookup_handle, gc, buddy) == 0) { /* Script was called - wait for answer some other time */ purple_debug_info("plainprpl", "Lookup by SCRIPT succeded. Start to ping %s\n", str_addr(&bstate->addr)); state = BUDDY_STATE_PING; state_step = 1; state_next = now + 1; } else if(addr_parse_full(&bstate->addr, addr_str, PLAIN_DEFAULT_PORT_STR, pstate->sockaf) == 0) { purple_debug_info("plainprpl", "Lookup by DNS succeded (%s). Start to ping %s\n", addr_str, str_addr(&bstate->addr)); //switch to ping state state = BUDDY_STATE_PING; state_step = 1; state_next = now + 1; } else { if(state_step == 0) { state_step = 4; } else if(state_step < (5*60)) { state_step *= 2; } purple_debug_info("plainprpl", "Resolve failed. Try again in %d seconds.\n", state_step); state_next = now + state_step; } } else if(state == BUDDY_STATE_PING) { //send ping if(bstate->time_recv < (now - (5*60))) { if(state_step < (5*60)) { state_step *= 2; state_next = now + state_step; send_msg(pstate, bstate, "/ping"); /* Set buddy status to online */ purple_prpl_got_user_status(account, bstate->name, PLAIN_STATUS_OFFLINE, NULL); } else { state = BUDDY_STATE_RESOLVE; state_step = 1; state_next = now + 1; } } else { state_step = 1; state_next = now + (5*60); } } else { purple_debug_info("plainprpl", "Invalid state: %d\n", state); } bstate->state = state; bstate->state_step = state_step; bstate->state_next = state_next; /* Get next time we need to do something here */ if (state_next < time_next) { time_next = state_next; } next: iter = iter->next; } pstate->time_next = time_next; purple_debug_info("plainprpl", "Next iteration in %d seconds.\n", (int)(time_next - now)); }
void handle_mcast( int rc, int sock_recv ) { char addrbuf[FULL_ADDSTRLEN+1]; char buf[512]; IP c_addr; socklen_t addrlen; int rc_recv; if( g_mcast_time <= time_now_sec() ) { if( kad_count_nodes( 0 ) == 0 ) { /* Join multicast group if possible */ if( g_mcast_registered == 0 && multicast_set_groups( sock_recv, &g_lpd_addr, gconf->dht_ifname, 1 ) == 0 ) { log_info( "LPD: No peers known. Joined multicast group." ); g_mcast_registered = 1; } if( g_mcast_registered == 1 ) { log_info( "LPD: Send multicast message to find nodes." ); /* Create message */ snprintf( buf, sizeof(buf), msg_fmt, str_addr( &g_lpd_addr, addrbuf ), atoi( gconf->dht_port ), g_infohash ); mcast_send_packets( buf, gconf->dht_ifname ); } } /* Cap number of received packets to 10 per minute */ g_packet_limit = 5 * PACKET_LIMIT_MAX; /* Try again in ~5 minutes */ g_mcast_time = time_add_min( 5 ); } if( rc <= 0 ) { return; } /* Reveice multicast ping */ addrlen = sizeof(IP); rc_recv = recvfrom( sock_recv, buf, sizeof(buf), 0, (struct sockaddr*) &c_addr, (socklen_t*) &addrlen ); if( rc_recv < 0 ) { log_warn( "LPD: Cannot receive multicast message: %s", strerror( errno ) ); return; } if( g_packet_limit < 0 ) { /* Too much traffic - leave multicast group for now */ if( g_mcast_registered == 1 && multicast_set_groups( sock_recv, &g_lpd_addr, gconf->dht_ifname, 0 ) == 0 ) { log_warn( "LPD: Too much traffic. Left multicast group." ); g_mcast_registered = 0; } return; } else { g_packet_limit--; } if( rc_recv >= sizeof(buf) ) { return; } else { buf[rc_recv] = '\0'; } int port = parse_packet( buf ); if( port > 0 ) { port_set( &c_addr, port ); log_debug( "LPD: Ping lonely peer at %s", str_addr( &c_addr, addrbuf ) ); kad_ping( &c_addr ); } else { log_debug( "LPD: Received invalid packet on multicast group." ); } }
int cmd_exec( REPLY *r, int argc, char **argv ) { char addrbuf[FULL_ADDSTRLEN+1]; time_t lifetime; int minutes; IP addrs[16]; int port; int count; static struct value_t *value; char *p; int rc = 0; if( argc == 0 ) { /* Print usage */ r_printf( r, cmd_usage ); if( r->allow_debug ) { r_printf( r, cmd_usage_debug ); } rc = 1; } else if( match( argv[0], "import" ) && argc == 2 ) { rc = cmd_import( r, argv[1] ); #if 0 } else if( match( argv[0], "lookup_node" ) && argc == 2 ) { /* Check searches for node */ rc = kad_lookup_node( argv[1], &addrs[0] ); if( rc == 0 ) { r_printf( r, "%s\n", str_addr( &addrs[0], addrbuf ) ); } else if( rc == 1 ) { r_printf( r ,"No search found.\n" ); rc = 1; } else if( rc == 2 ) { r_printf( r ,"Invalid id format. 20 digit hex string expected.\n" ); rc = 1; } else { rc = 1; } #endif } else if( match( argv[0], "lookup" ) && argc == 2 ) { size_t num = N_ELEMS(addrs); size_t i; /* Check searches for node */ rc = kad_lookup_value( argv[1], addrs, &num ); if( rc >= 0 && num > 0 ) { for( i = 0; i < num; ++i ) { r_printf( r, "%s\n", str_addr( &addrs[i], addrbuf ) ); } } else if( rc < 0 ) { r_printf( r ,"Some error occured.\n" ); rc = 1; } else if( rc == 0 ) { r_printf( r ,"Search in progress.\n" ); rc = 1; } else { r_printf( r ,"Search started.\n" ); rc = 1; } } else if( match( argv[0], "status" ) && argc == 1 ) { /* Print node id and statistics */ cmd_print_status( r ); } else if( match( argv[0], "announce" ) && (argc == 1 || argc == 2 || argc == 3) ) { if( argc == 1 ) { /* Announce all values; does not update value.refreshed */ count = 0; value = values_get(); while( value ) { kad_announce_once( value->id, value->port ); count++; value = value->next; } r_printf( r ,"%d announcements started.\n", count ); rc = 0; goto end; } else if( argc == 2 ) { minutes = 0; lifetime = 0; } else if( argc == 3 ) { minutes = atoi( argv[2] ); if( minutes < 0 ) { minutes = 0; lifetime = LONG_MAX; } else { /* Round up to multiple of 30 minutes */ minutes = (30 * (minutes/30 + 1)); lifetime = (time_now_sec() + (minutes * 60)); } } else { /* Make compilers happy */ exit( 1 ); } int is_random_port = 0; /* Find <id>:<port> delimiter */ p = strchr( argv[1], ':' ); if( p ) { *p = '\0'; port = port_parse( p + 1, -1 ); } else { /* A valid port will be choosen inside kad_announce() */ port = 0; is_random_port = 1; } if( kad_announce( argv[1], port, lifetime ) >= 0 ) { #ifdef FWD if( !is_random_port ) { forwardings_add( port, lifetime); } #endif if( lifetime == 0 ) { r_printf( r ,"Start single announcement now.\n" ); } else if( lifetime == LONG_MAX ) { r_printf( r ,"Start regular announcements for the entire run time (%sport %d).\n", (is_random_port ? "random " : ""), port ); } else { r_printf( r ,"Start regular announcements for %d minutes (%sport %d).\n", minutes, (is_random_port ? "random " : ""), port ); } } else { r_printf( r ,"Invalid port or query too long.\n" ); rc = 1; } } else if( match( argv[0], "blacklist" ) && argc == 2 ) { rc = cmd_blacklist( r, argv[1] ); } else if( match( argv[0], "export" ) && argc == 1 ) { rc = cmd_export( r ); } else if( match( argv[0], "list" ) && argc == 2 && r->allow_debug ) { if( gconf->is_daemon == 1 ) { r_printf( r ,"The 'list' command is not available while KadNode runs as daemon.\n" ); rc = 1; goto end; } else if( match( argv[1], "blacklist" ) ) { kad_debug_blacklist( STDOUT_FILENO ); rc = 0; } else if( match( argv[1], "buckets" ) ) { kad_debug_buckets( STDOUT_FILENO ); rc = 0; } else if( match( argv[1], "constants" ) ) { kad_debug_constants( STDOUT_FILENO ); rc = 0; #ifdef FWD } else if( match( argv[1], "forwardings" ) ) { forwardings_debug( STDOUT_FILENO ); rc = 0; #endif #ifdef AUTH } else if( match( argv[1], "pkeys" ) ) { auth_debug_pkeys( STDOUT_FILENO ); rc = 0; } else if( match( argv[1], "skeys" ) ) { auth_debug_skeys( STDOUT_FILENO ); rc = 0; #endif } else if( match( argv[1], "results" ) ) { results_debug( STDOUT_FILENO ); rc = 0; } else if( match( argv[1], "searches" ) ) { kad_debug_searches( STDOUT_FILENO ); rc = 0; } else if( match( argv[1], "storage" ) ) { kad_debug_storage( STDOUT_FILENO ); rc = 0; } else if( match( argv[1], "values" ) ) { values_debug( STDOUT_FILENO ); rc = 0; } else { dprintf( STDERR_FILENO, "Unknown argument.\n" ); rc = 1; } r_printf( r ,"\nOutput send to console.\n" ); } else { /* print usage */ r_printf( r, cmd_usage ); if( r->allow_debug ) { r_printf( r, cmd_usage_debug ); } rc = 1; } end: ; return rc; }
int net_bind( const char *name, const char* addr, const char* port, const char* ifce, int protocol, int af ) { char addrbuf[FULL_ADDSTRLEN+1]; int sock; int val; IP sockaddr; if( af != AF_INET && af != AF_INET6 ) { log_err( "NET: Unknown address family value." ); return -1; } if( addr_parse( &sockaddr, addr, port, af ) != 0 ) { log_err( "NET: Failed to parse IP address '%s' and port '%s'.", addr, port ); return -1; } if( protocol == IPPROTO_TCP ) { sock = socket( sockaddr.ss_family, SOCK_STREAM, IPPROTO_TCP ); } else if( protocol == IPPROTO_UDP ) { sock = socket( sockaddr.ss_family, SOCK_DGRAM, IPPROTO_UDP ); } else { sock = -1; } if( sock < 0 ) { log_err( "NET: Failed to create socket: %s", strerror( errno ) ); return -1; } val = 1; if ( setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val) ) < 0 ) { close( sock ); log_err( "NET: Failed to set socket option SO_REUSEADDR: %s", strerror( errno )); return -1; } if( ifce && setsockopt( sock, SOL_SOCKET, SO_BINDTODEVICE, ifce, strlen( ifce ) ) ) { close( sock ); log_err( "NET: Unable to bind to device '%s': %s", ifce, strerror( errno ) ); return -1; } if( af == AF_INET6 ) { val = 1; if( setsockopt( sock, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val) ) < 0 ) { close( sock ); log_err( "NET: Failed to set socket option IPV6_V6ONLY: %s", strerror( errno )); return -1; } } if( bind( sock, (struct sockaddr*) &sockaddr, sizeof(IP) ) < 0 ) { close( sock ); log_err( "NET: Failed to bind socket to address: '%s'", strerror( errno ) ); return -1; } if( net_set_nonblocking( sock ) < 0 ) { close( sock ); log_err( "NET: Failed to make socket nonblocking: '%s'", strerror( errno ) ); return -1; } if( protocol == IPPROTO_TCP && listen( sock, 5 ) < 0 ) { close( sock ); log_err( "NET: Failed to listen on socket: '%s'", strerror( errno ) ); return -1; } log_info( ifce ? "%s: Bind to %s, interface %s" : "%s: Bind to %s" , name, str_addr( &sockaddr, addrbuf ), ifce ); return sock; }