Esempio n. 1
0
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);
	  }
     }
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
/* 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();
}
Esempio n. 5
0
/* 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();
}
Esempio n. 6
0
/* 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();
}
Esempio n. 7
0
/* 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();
}
Esempio n. 8
0
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;
	}
}
Esempio n. 9
0
/* 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;
}
Esempio n. 10
0
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;
}
Esempio n. 11
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;
	}
}
Esempio n. 12
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 ) );
		}
	}
}
Esempio n. 13
0
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();
}
Esempio n. 14
0
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;
}
Esempio n. 15
0
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;
}
Esempio n. 16
0
/*
* 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 );
	}
}
Esempio n. 17
0
/* 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;
}
Esempio n. 18
0
char *str_addr4( const IP4 *addr, char addrbuf[] ) {
	return str_addr( (const IP *)addr, addrbuf );
}
Esempio n. 19
0
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
}
Esempio n. 20
0
/* 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));
}
Esempio n. 21
0
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." );
	}
}
Esempio n. 22
0
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;
}
Esempio n. 23
0
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;
}