Example #1
0
void init() {
	char temp[1024], nick[1024], addr[1024], newaddr[NET_MAX_ADDRESS_LENGTH];
	NET_DRIVERLIST drv;
	drv = net_driverlist_create();
	net_driverlist_clear (drv);
	net_driverlist_add (drv, netdriver);

	if (!net_initdrivers (drv)) {
		printf("Error initialising driver.\n");
		exit (1);
	}

	printf ("Enter target address: ");
	fgets (addr, 1024, stdin);
	while (strchr(addr,'\n')) *strchr(addr,'\n')=0;

	printf ("Enter nickname: ");
	fgets (nick, 10, stdin);
	while (strchr(nick,'\n')) *strchr(nick,'\n')=0;

	if (!(chan = net_openchannel (netdriver, NULL))) {
		printf ("Unable to open channel.\n");
		exit (2);
	}

	printf ("Connecting to %s...\n", addr);

	net_assigntarget (chan, addr);
	sprintf (temp, "%c%s", CHAT_MAGIC, nick);
	net_send (chan, temp, strlen (temp));

	while ((!net_query (chan))/* && !conio_kbhit()*/);

	if (0/*conio_kbhit()*/) {
		conio_getch();
		printf ("Aborted.\n");
		exit (3);
	}

	{
		int x = net_receive (chan, temp, 1024, newaddr);
		if (x == -1) {
			printf ("Receive error.\n");
			exit (5);
		}
		temp[x] = 0;
	}

	if (strcmp (temp, "OK")) {
		printf ("Connection refused.\n");
		exit (4);
	}

	printf ("Connection accepted, redirecting... ");
	fflush (stdout);
	net_assigntarget (chan, newaddr);
	printf ("done.\n");
}
Example #2
0
/* poll_listen:
 *  Here we check for an incoming connection, and if there is one we
 *  fill in `newconn' with our data pointer for it and the addresses,
 *  and return nonzero.  Otherwise return 0.
 */
static int poll_listen (NET_CONN *conn, NET_CONN *newconn)
{
	struct conn_data_t *data;
	char buffer[12], buffer2[8+NET_MAX_ADDRESS_LENGTH] = { 0, 0, 0, 0, 0, 0, 0, 0 };
	char addr[NET_MAX_ADDRESS_LENGTH];
	int x;

	int count = 32; /* maximum number of packets to process */
	while (net_query (((struct conn_data_t *)conn->data)->chan) && count-- > 0) {
		if ((net_receive (((struct conn_data_t *)conn->data)->chan, buffer, 12, addr) == 12) && !memcmp (buffer, "connect", 8)) {
			newconn->data = data = malloc (sizeof *data);
			if (!data) continue;

			if (create_queues (newconn)) {
				free (data);
				continue;
			}

			data->conns = NULL;
			
			x = get_channel (
				((struct conn_data_t *)conn->data)->conns, addr,
				(buffer[8] << 24) + (buffer[9] << 16) +
				(buffer[10] << 8) + buffer[11],
				conn->type, NULL, &data->chan, data
			);
			
			if (x) {
				data->referer = conn->data;

				/* tell new channel where to send in future */
				net_assigntarget (data->chan, addr);

				/* send reply now with address of new channel, through
				 * listening conn so it can get through NATs */
				net_assigntarget (((struct conn_data_t *)conn->data)->chan, addr);
				strcpy (buffer2+8, net_getlocaladdress (data->chan));
				net_send (((struct conn_data_t *)conn->data)->chan, buffer2, 8+NET_MAX_ADDRESS_LENGTH);
			}
			
			if (x >= 0) {
				destroy_queues (newconn);
				free (data);
				continue;
			}

			strcpy (newconn->peer_addr, addr);

			return 1;
		}
	}

	return 0;
}
Example #3
0
/* connect:
 *  Set the target address and send the first connection request.  This
 *  might not get through of course; later we can just repeat the send
 *  statement because the target address is already set.  No need to store
 *  it anywhere.
 */
static int connect (NET_CONN *conn, const char *target)
{
	int id;
	static int next_id = 0;
	struct conn_data_t *data = conn->data;

	/* The id is a compound of the current time (with 1 second 
	 * granularity), and an increasing counter.  The time is needed
	 * because the counter resets when you restart the program, and 
	 * the counter is needed because of the granularity of the time. */

	/* Strictly, this line needs a mutex, but there's nowhere around 
	 * here we can call `MUTEX_CREATE'. */
	id = (next_id++ << 16) + (time(NULL) & 0xffff);

	strcpy (data->connect_string, "connect");
	data->connect_string[8] = (id >> 24) & 0xff;
	data->connect_string[9] = (id >> 16) & 0xff;
	data->connect_string[10] = (id >> 8) & 0xff;
	data->connect_string[11] = id & 0xff;
	
	if (net_assigntarget (data->chan, target)) return 1;
	if (net_send (data->chan, data->connect_string, 12)) return 2;
	data->connect_timestamp = __libnet_timer_func();
	return 0;
}
Example #4
0
/* poll_connect:
 *  This function does two things.  Firstly it checks for a response from 
 *  the server.  If there's no response, it then resends the connection 
 *  request.
 *
 *  The possible problem here is that the server's response might just be
 *  delayed.  The best way I can see around this problem is for the server
 *  to keep an eye on the return addresses of the connection attempts, and
 *  not open a fresh channel each time a duplicate of an old packet arrives.
 *  This actually kills two birds with one stone, since if either the 
 *  client's request packet or the server's response packet are dropped, the
 *  client will eventually resend, causing the server to send an identical 
 *  response.
 *
 *  Later note:  In fact we needed to introduce an almost-unique identifier
 *  to pass as well, since the channel's address may be reused later on.
 */
static int poll_connect (NET_CONN *conn)
{
	struct conn_data_t *data = conn->data;
	char buffer[8+NET_MAX_ADDRESS_LENGTH];
	char addr[NET_MAX_ADDRESS_LENGTH];
	
	if ((net_receive (data->chan, buffer, 8+NET_MAX_ADDRESS_LENGTH, addr) == 8+NET_MAX_ADDRESS_LENGTH) && (!memcmp (buffer, "\0\0\0\0\0\0\0", 8))) {
		net_fixupaddress_channel(data->chan, &buffer[8], addr);
		net_assigntarget (data->chan, addr);
		strcpy (conn->peer_addr, addr);
		return 1;
	}
	/* No response */
	{
		unsigned long clock_value = __libnet_timer_func();
		if ((unsigned)(clock_value - data->connect_timestamp) > RESEND_RATE) {
			net_send (data->chan, data->connect_string, 8);
			data->connect_timestamp = clock_value;
		}
	}
	return 0;
}
Example #5
0
int main (int argc, char **argv)
{
    NET_CONN *listen, *conn = NULL;
    NET_CHANNEL *chan;
    char remote[NET_MAX_ADDRESS_LENGTH], buf[NET_MAX_ADDRESS_LENGTH];
    char *p, c;
    int server = -1;

    if (argc > 1) {
        if (!strcmp (argv[1], "server")) server = 1;
        else if (!strcmp (argv[1], "client")) server = 0;
    }
    if (server == -1) {
        puts ("Pass `server' or `client' on the command line.");
        return 1;
    }

    net_init();
    net_detectdrivers(net_drivers_all);
    net_initdrivers(net_drivers_all);

    if (server) {
        listen = net_openconn(DRIVER, "");
        net_listen(listen);
        while (!conn) 
            conn = net_poll_listen(listen);
    } else {
        conn = net_openconn(DRIVER, NULL);
        if (net_connect_wait_time(conn, ADDRESS, 5) != 0) {
            printf("Error connecting\n");
            return 1;
        }
    }

    chan = net_openchannel(DRIVER, NULL);
    p = net_getlocaladdress(chan);
    net_send_rdm(conn, p, strlen(p) + 1);

    while (!net_query_rdm(conn)) ;
    net_receive_rdm(conn, remote, sizeof remote);

    printf ("Address before fixing: %s\n", remote);

    if (net_fixupaddress_conn(conn, remote, buf) != 0) {
	printf("Didn't work\n");
	return 1;
    }

    printf ("Address after fixing: %s\n", buf);

    printf("assigning target: %s\n", buf);
    net_assigntarget(chan, buf);

    do {
	c = fgetc(stdin);
	if (c == '1') 
	    net_send(chan, "** Channel", 11);
	else if (c == '2')
	    net_send_rdm(conn, "** Conn", 8);

	while (net_query(chan)) {
	    net_receive(chan, buf, sizeof buf, NULL);
	    printf("%s\n", buf);
	}

	while (net_query_rdm(conn)) {
	    net_receive_rdm(conn, buf, sizeof buf);
	    printf("%s\n", buf);
	}
    } while (c != 'q');

    return 0;
}