Пример #1
0
/* Authentication (Client side) */
int auth_client(int fd, struct vtun_host *host, int * reason)
{
	char buf[VTUN_MESG_SIZE], chal[VTUN_CHAL_SIZE];
	int stage, success=0 ;
	
	stage = ST_INIT;
    *reason = D_NOREAD;
	while( readn_t(fd, buf, VTUN_MESG_SIZE, vtun.timeout) > 0 ){
        *reason = D_OTHER;
	   buf[sizeof(buf)-1]='\0';
	   switch( stage ){
		case ST_INIT:
            if (!strncmp(buf, "VTRUNKD", 7)) {
		      stage = ST_HOST;
		      print_p(fd,"HOST: %s\n",host->host);
		      continue;
	           }
               *reason = D_GREET;
		   break;	

	        case ST_HOST:
		   if( !strncmp(buf,"OK",2) && cs2cl(buf,chal)){
		      stage = ST_CHAL;
					
		      encrypt_chal(chal,host->passwd);
		      print_p(fd,"CHAL: %s\n", cl2cs(chal));

		      continue;
	   	   }
           *reason = D_CHAL;
		   break;	
	
	        case ST_CHAL:
		   if( !strncmp(buf,"OK",2) && cf2bf(buf,host) )
		      success = 1;
           else *reason = D_PWD;
		   break;
	   }
	   break;
	}

	return success;
}
Пример #2
0
/* Authentication (Server side) */
struct vtun_host * auth_server(int fd)
{
        char chal_req[VTUN_CHAL_SIZE], chal_res[VTUN_CHAL_SIZE];	
	char buf[VTUN_MESG_SIZE], *str1, *str2;
        struct vtun_host *h = NULL;
	char *host = NULL;
	int  stage;

        set_title("authentication");

	print_p(fd,"VTUN server ver %s\n",VTUN_VER);

	stage = ST_HOST;

	while( readn_t(fd, buf, VTUN_MESG_SIZE, vtun.timeout) > 0 ){
	   buf[sizeof(buf)-1]='\0';
	   strtok(buf,"\r\n");

	   if( !(str1=strtok(buf," :")) )
	      break;
	   if( !(str2=strtok(NULL," :")) )
	      break;

	   switch( stage ){
	     case ST_HOST:
	        if( !strcmp(str1,"HOST") ){
		   host = strdup(str2);

		   gen_chal(chal_req);
		   print_p(fd,"OK CHAL: %s\n", cl2cs(chal_req));

		   stage = ST_CHAL;
		   continue;
	        }
		break;
	     case ST_CHAL:
	        if( !strcmp(str1,"CHAL") ){
		   if( !cs2cl(str2,chal_res) )
		      break; 
		   
		   if( !(h = find_host(host)) )
		      break;

		   decrypt_chal(chal_res, h->passwd);   		
	
		   if( !memcmp(chal_req, chal_res, VTUN_CHAL_SIZE) ){
		      /* Auth successeful. */

		      /* Lock host */	
		      if( lock_host(h) < 0 ){
		         /* Multiple connections are denied */
		         h = NULL;
		         break;
		      }	
		      print_p(fd,"OK FLAGS: %s\n", bf2cf(h)); 
 		   } else
		      h = NULL;
	        }
		break;
 	   }
	   break;
	}

	if( host )
	   free(host);

	if( !h )
	   print_p(fd,"ERR\n");	

	return h;
}
Пример #3
0
//add by adonis for multiple interfaces
int udp_session_fs1(struct vtun_host *host) {
	struct sockaddr_in saddr;
	short port;
	int s, opt;
	vtun_syslog(LOG_ERR, "in udp_session_fs1");
	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
		vtun_syslog(LOG_ERR, "Can't create socket");
		return -1;
	}

	opt = 1;
	setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
	fcntl(s, F_SETFL, O_NONBLOCK);
	/* Set local address and port */

	vtun_syslog(LOG_ERR, "in local_addr");
	local_addr(&saddr, host, 1);
	vtun_syslog(LOG_ERR, "after local_addr");
	vtun_syslog(LOG_ERR, "debug %d", host->sport[1]);
	vtun_syslog(LOG_ERR, "debug %d, %s", host->sport[1], host->saddr[1].ip);
	saddr.sin_port = host->sport[1];
	saddr.sin_addr.s_addr = inet_addr(host->saddr[1].ip);
	vtun_syslog(LOG_ERR, "before bind");
	if (bind(s, (struct sockaddr *) &saddr, sizeof(saddr))) {
		vtun_syslog(LOG_ERR, "Can't bind to the socket %s", strerror(errno));
		return -1;
	}

	opt = sizeof(saddr);
	if (getsockname(s, (struct sockaddr *) &saddr, &opt)) {
		vtun_syslog(LOG_ERR, "Can't get socket name");
		return -1;
	}

	vtun_syslog(LOG_ERR, "after bind");
	/* Write port of the new UDP socket */
	port = saddr.sin_port;
	if (write_n(host->rmt_fd2, (char *) &port, sizeof(short)) < 0) {
		vtun_syslog(LOG_ERR, "Can't write port number");
		return -1;
	}
	host->sopt.lport = htons(port);

	vtun_syslog(LOG_ERR, "after port ex send");
	/* Read port of the other's end UDP socket */
	if (readn_t(host->rmt_fd2, &port, sizeof(short), host->timeout) < 0) {
		vtun_syslog(LOG_ERR, "Can't read port number %s", strerror(errno));
		return -1;
	}

	vtun_syslog(LOG_ERR, "after port ex recv");
	opt = sizeof(saddr);
	if (getpeername(host->rmt_fd2, (struct sockaddr *) &saddr, &opt)) {
		vtun_syslog(LOG_ERR, "Can't get peer name");
		return -1;
	}

	saddr.sin_port = port;
	if (connect(s, (struct sockaddr *) &saddr, sizeof(saddr))) {
		vtun_syslog(LOG_ERR, "Can't connect socket");
		return -1;
	}
	host->sopt.rport = htons(port);
	host->rmt_sock2 = saddr;
	/* Close TCP socket and replace with UDP socket */
	close(host->rmt_fd2);
	host->rmt_fd2 = s;
	//add by Kai for multiple interfaces
	host->fs[1].saddr = saddr;
	host->fs[1].fd = s;
	host->fs[1].fd_flag = 1;
	//end add

	vtun_syslog(LOG_INFO, "UDP 1 connection initialized");
	return s;
}
Пример #4
0
int udp_session(struct vtun_host *host)
{
    struct sockaddr_in saddr;
    short port;
    int s, opt;
    extern int is_rmt_fd_connected;

    if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
	vtun_syslog(LOG_ERR, "Can't create socket");
	return -1;
    }

    opt = 1;
    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

    /* Set local address and port */
    local_addr(&saddr, host, 1);
    if (bind(s, (struct sockaddr *) &saddr, sizeof(saddr))) {
	vtun_syslog(LOG_ERR, "Can't bind to the socket");
	return -1;
    }

    opt = sizeof(saddr);
    if (getsockname(s, (struct sockaddr *) &saddr, &opt)) {
	vtun_syslog(LOG_ERR, "Can't get socket name");
	return -1;
    }

    /* Write port of the new UDP socket */
    port = saddr.sin_port;
    if (write_n(host->rmt_fd, (char *) &port, sizeof(short)) < 0) {
	vtun_syslog(LOG_ERR, "Can't write port number");
	return -1;
    }
    host->sopt.lport = htons(port);

    /* Read port of the other's end UDP socket */
    if (readn_t(host->rmt_fd, &port, sizeof(short), host->timeout) < 0) {
	vtun_syslog(LOG_ERR, "Can't read port number %s", strerror(errno));
	return -1;
    }

    opt = sizeof(saddr);
    if (getpeername(host->rmt_fd, (struct sockaddr *) &saddr, &opt)) {
	vtun_syslog(LOG_ERR, "Can't get peer name");
	return -1;
    }

    saddr.sin_port = port;

    /* if the config says to delay the UDP connection, we wait for an
       incoming packet and then force a connection back.  We need to
       put this here because we need to keep that incoming triggering
       packet and pass it back up the chain. */

    if (VTUN_USE_NAT_HACK(host))
	is_rmt_fd_connected = 0;
    else {
	if (connect(s, (struct sockaddr *) &saddr, sizeof(saddr))) {
	    vtun_syslog(LOG_ERR, "Can't connect socket");
	    return -1;
	}
	is_rmt_fd_connected = 1;
    }

    host->sopt.rport = htons(port);

    /* Close TCP socket and replace with UDP socket */
    close(host->rmt_fd);
    host->rmt_fd = s;

    vtun_syslog(LOG_INFO, "UDP connection initialized");
    return s;
}
Пример #5
0
int udp_session2(struct vtun_host *host) {
	struct sockaddr_in saddr;
	short port;
	int s, opt;

	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
		vtun_syslog(LOG_ERR, "Can't create socket");
		return -1;
	}

	opt = 1;
	setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
	fcntl(s, F_SETFL, O_NONBLOCK);
	/* Set local address and port */
	local_addr(&saddr, host, 1);
	saddr.sin_port = host->sport[0];
	saddr.sin_addr.s_addr = inet_addr(host->saddr[0].ip);
	if (bind(s, (struct sockaddr *) &saddr, sizeof(saddr))) {
		vtun_syslog(LOG_ERR, "Can't bind to the socket %s", strerror(errno));
		return -1;
	}

	opt = sizeof(saddr);
	if (getsockname(s, (struct sockaddr *) &saddr, &opt)) {
		vtun_syslog(LOG_ERR, "Can't get socket name");
		return -1;
	}

	/* Write port of the new UDP socket */
	port = saddr.sin_port;
	if (write_n(host->rmt_fd, (char *) &port, sizeof(short)) < 0) {
		vtun_syslog(LOG_ERR, "Can't write port number");
		return -1;
	}
	host->sopt.lport = htons(port);

	/* Read port of the other's end UDP socket */
	if (readn_t(host->rmt_fd, &port, sizeof(short), host->timeout) < 0) {
		vtun_syslog(LOG_ERR, "Can't read port number %s", strerror(errno));
		return -1;
	}

	opt = sizeof(saddr);
	if (getpeername(host->rmt_fd, (struct sockaddr *) &saddr, &opt)) {
		vtun_syslog(LOG_ERR, "Can't get peer name");
		return -1;
	}

	saddr.sin_port = port;
	if (connect(s, (struct sockaddr *) &saddr, sizeof(saddr))) {
		vtun_syslog(LOG_ERR, "Can't connect socket");
		return -1;
	}
	host->sopt.rport = htons(port);
	host->rmt_sock = saddr;
	/* Close TCP socket and replace with UDP socket */
	close(host->rmt_fd);
	host->rmt_fd = s;

	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
		vtun_syslog(LOG_ERR, "Can't create socket2");
		return -1;
	}

	opt = 1;
	setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
	fcntl(s, F_SETFL, O_NONBLOCK);

	/* Set local address and port */
	saddr.sin_port = host->sport[1];
	saddr.sin_addr.s_addr = inet_addr(host->saddr[1].ip);

	vtun_syslog(LOG_ERR, "address %s:%d", host->saddr[0].ip, host->sport[0]);
	vtun_syslog(LOG_ERR, "address %s:%d", host->saddr[1].ip, host->sport[1]);
	vtun_syslog(LOG_ERR, "address %s:%d", inet_ntoa(saddr.sin_addr),
			ntohs(saddr.sin_port));
	if (bind(s, (struct sockaddr *) &saddr, sizeof(saddr))) {
		vtun_syslog(LOG_ERR, "Can't bind to the socket2 (%d:%s)", errno,
				strerror(errno));
		return -1;
	}

	saddr.sin_port = host->dport[1];
	saddr.sin_addr.s_addr = inet_addr(host->daddr[1].ip);
	if (connect(s, (struct sockaddr *) &saddr, sizeof(saddr))) {
		vtun_syslog(LOG_ERR, "Can't connect socket2 ");
		return -1;
	}
	host->rmt_sock2 = saddr;
	host->rmt_fd2 = s;

	//vtun.rmt_sock2 = saddr;
	//vtun.rmt_fd2 = s;
	vtun_syslog(LOG_INFO, "UDP connection initialized");
	return s;
}
Пример #6
0
/*
 * Establish UDP session with host connected to fd(socket).
 * Returns connected UDP socket or -1 on error.
 */
int udp_session(struct vtun_host *host) {
	struct sockaddr_in saddr;
	short port;
	int s, opt;
	int buflen = 10;
	char buf[10];
	char ipstr[INET_ADDRSTRLEN];
	vtun_syslog(LOG_INFO, "UDP connection initialized %d,%d", host->rmt_fd,
			host->rmt_fd2);
	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
		vtun_syslog(LOG_ERR, "Can't create socket");
		return -1;
	}
	opt = 1;
	setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
	fcntl(s, F_SETFL, O_NONBLOCK);

	/* Set local address and port */
	local_addr(&saddr, host, 1);
	saddr.sin_port = htons(host->sport[0]);
	saddr.sin_addr.s_addr = inet_addr(host->saddr[0].ip);
	errno = 0;
	if (bind(s, (struct sockaddr *) &saddr, sizeof(saddr))) {
		vtun_syslog(LOG_ERR, "Can't bind to the socket %s (%s:%d)",
				strerror(errno), host->saddr[0].ip, host->sport[0]);
		return -1;
	}

	opt = sizeof(saddr);
	if (getsockname(s, (struct sockaddr *) &saddr, &opt)) {
		vtun_syslog(LOG_ERR, "Can't get socket name");
		return -1;
	}
	host->fs[0].saddr = saddr;
	/* if we are not just binding port number then we are server*/
	if (host->role == 1) {
		vtun_syslog(LOG_INFO, "udp_session for server 1");
		/* Write port of the new UDP socket */
		port = saddr.sin_port;
		if (write_n(host->rmt_fd, (char *) &port, sizeof(short)) < 0) {
			vtun_syslog(LOG_ERR, "Can't write port number");
			return -1;
		}
		vtun_syslog(LOG_INFO, "Waiting for UDP ACK 1, wrote port %d", port);
		opt = sizeof(saddr);
		while (recvfrom(s, (char *) &port, sizeof(short), 0,
				(struct sockaddr *) &saddr, &opt) <= 0)
			;
		vtun_syslog(LOG_INFO, "UDP ACK 1 from  %s:%d",
				inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));

		host->fs[0].daddr.sin_family = saddr.sin_family;
		host->fs[0].daddr.sin_port = saddr.sin_port;
		host->fs[0].daddr.sin_addr.s_addr = saddr.sin_addr.s_addr;

		inet_ntop(AF_INET, &(host->fs[0].daddr.sin_addr), ipstr,
				INET_ADDRSTRLEN);
		vtun_syslog(LOG_INFO, "%s:%d", ipstr,
				ntohs(host->fs[0].daddr.sin_port));

		if (connect(s, (struct sockaddr *) &saddr, sizeof(saddr))) {
			vtun_syslog(LOG_ERR, "Can't connect socket");
			return -1;
		}

		write_n(s, (char *) &port, sizeof(short));
		vtun_syslog(LOG_INFO, "FINAL ACK SENT 1");

	} else {

		//vtun_syslog(LOG_INFO,"udp_session for client 1");
		/* Read port of the other's end UDP socket */
		if (readn_t(host->rmt_fd, (char *) &port, sizeof(short), host->timeout)
				< 0) {
			vtun_syslog(LOG_ERR, "Can't read port number %s", strerror(errno));
			return -1;
		}
		vtun_syslog(LOG_INFO, "Recieved port %d info from server 1", port);
		opt = sizeof(saddr);
		if (getpeername(host->rmt_fd, (struct sockaddr *) &saddr, &opt)) {
			vtun_syslog(LOG_ERR, "Can't get peer name");
			return -1;
		}

		saddr.sin_port = port;
		sendto(s, (char *) &port, sizeof(short), 0, (struct sockaddr *) &saddr,
				opt);
		vtun_syslog(LOG_INFO, "Sent ACK on UDP 1");
		host->fs[0].daddr = saddr;
		if (connect(s, (struct sockaddr *) &saddr, sizeof(saddr))) {
			vtun_syslog(LOG_ERR, "Can't connect socket");
			return -1;
		}

		read_n(s, (char *) &port, sizeof(short));
		vtun_syslog(LOG_INFO, "Connected & Recived final ACK 1");
	}
	/* Why we need this ??*/
	host->sopt.rport = htons(port);
	host->rmt_sock = saddr;
	/* Close TCP socket and replace with UDP socket */
	close(host->rmt_fd);
	host->rmt_fd = s;
	//add by Kai for multiple interfaces
	// host->fs[0].daddr = saddr;

	host->fs[0].fd = s;
	host->fs[0].fd_flag = 1;

	s = 0;
	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
		vtun_syslog(LOG_ERR, "Can't create socket");
		return -1;
	}

	opt = 1;
	setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
	fcntl(s, F_SETFL, O_NONBLOCK);
	/* Set local address and port */
	local_addr(&saddr, host, 1);
	saddr.sin_port = htons(host->sport[1]);
	saddr.sin_addr.s_addr = inet_addr(host->saddr[1].ip);
	if (bind(s, (struct sockaddr *) &saddr, sizeof(saddr))) {
		vtun_syslog(LOG_ERR, "Can't bind to the socket");
		return -1;
	}

	opt = sizeof(saddr);
	if (getsockname(s, (struct sockaddr *) &saddr, &opt)) {
		vtun_syslog(LOG_ERR, "Can't get socket name");
		return -1;
	}
	host->fs[1].saddr = saddr;
	/* if we are not just binding port number then we are server*/
	//if(saddr.sin_addr.s_addr == inet_addr("0.0.0.0")){
	if (host->role == 1) {
		vtun_syslog(LOG_INFO, "udp_session for server 2");
		/* Write port of the new UDP socket */
		port = saddr.sin_port;
		if (write_n(host->rmt_fd2, (char *) &port, sizeof(short)) < 0) {
			vtun_syslog(LOG_ERR, "Can't write port number");
			return -1;
		}
		vtun_syslog(LOG_INFO, "Waiting for UDP ACK 2 wrote port %d", port);
		opt = sizeof(saddr);
		while (recvfrom(s, (char *) &port, sizeof(short), 0,
				(struct sockaddr *) &saddr, &opt) <= 0)
			;
		vtun_syslog(LOG_INFO, "UDP ACK 2 from  %s:%d",
				inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
		host->fs[1].daddr.sin_family = saddr.sin_family;
		host->fs[1].daddr.sin_port = saddr.sin_port;
		host->fs[1].daddr.sin_addr.s_addr = saddr.sin_addr.s_addr;

		inet_ntop(AF_INET, &(host->fs[1].daddr.sin_addr), ipstr,
				INET_ADDRSTRLEN);
		vtun_syslog(LOG_INFO, "%s:%d", ipstr,
				ntohs(host->fs[1].daddr.sin_port));

		if (connect(s, (struct sockaddr *) &saddr, sizeof(saddr))) {
			vtun_syslog(LOG_ERR, "Can't connect socket");
			return -1;
		}
		write_n(s, (char *) &port, sizeof(short));
		vtun_syslog(LOG_INFO, "FINAL ACK SENT 2");
	} else {
		vtun_syslog(LOG_INFO, "udp_session for client 2");
		/* Read port of the other's end UDP socket */
		if (readn_t(host->rmt_fd2, (char *) &port, sizeof(short), host->timeout)
				< 0) {
			vtun_syslog(LOG_ERR, "Can't read port number %s", strerror(errno));
			return -1;
		}
		opt = sizeof(saddr);
		if (getpeername(host->rmt_fd2, (struct sockaddr *) &saddr, &opt)) {
			vtun_syslog(LOG_ERR, "Can't get peer name");
			return -1;
		}

		saddr.sin_port = port;
		vtun_syslog(LOG_INFO, "Recieved port %d info from server 2", port);
		sendto(s, (char *) &port, sizeof(short), 0, (struct sockaddr *) &saddr,
				opt);
		host->fs[1].daddr = saddr;
		if (connect(s, (struct sockaddr *) &saddr, sizeof(saddr))) {
			vtun_syslog(LOG_ERR, "Can't connect socket");
			return -1;
		}

		read_n(s, (char *) &port, sizeof(short));
		vtun_syslog(LOG_INFO, "Connected & Recived final ACK 2");
	}
	host->rmt_sock2 = saddr;
	/* Close TCP socket and replace with UDP socket */
	close(host->rmt_fd2);
	host->rmt_fd2 = s;
	//add by Kai for multiple interfaces
	host->fs[1].fd = s;
	host->fs[1].fd_flag = 1;
	inet_ntop(AF_INET, &(host->fs[0].saddr.sin_addr), ipstr, INET_ADDRSTRLEN);
	vtun_syslog(LOG_INFO, " fd is %s:%d ->", ipstr,
			ntohs(host->fs[0].saddr.sin_port));
	inet_ntop(AF_INET, &(host->fs[0].daddr.sin_addr), ipstr, INET_ADDRSTRLEN);
	vtun_syslog(LOG_INFO, " fd is %s:%d <-", ipstr,
			ntohs(host->fs[0].daddr.sin_port));
	inet_ntop(AF_INET, &(host->fs[1].saddr.sin_addr), ipstr, INET_ADDRSTRLEN);
	vtun_syslog(LOG_INFO, " fd is %s:%d ->", ipstr,
			ntohs(host->fs[1].saddr.sin_port));
	inet_ntop(AF_INET, &(host->fs[1].daddr.sin_addr), ipstr, INET_ADDRSTRLEN);
	vtun_syslog(LOG_INFO, " fd is %s:%d <-", ipstr,
			ntohs(host->fs[1].daddr.sin_port));
	host->fs[0].saddr.sin_port = htons(4444);
	host->fs[0].daddr.sin_port = htons(4444);
	host->fs[1].saddr.sin_port = htons(4444);
	host->fs[1].daddr.sin_port = htons(4444);
	/*
	 host->fs[0].saddr.sin_port = htons(host->dport[1]+10);
	 host->fs[0].daddr.sin_port = htons(host->dport[1]+10);
	 host->fs[1].saddr.sin_port = htons(host->dport[1]+10);
	 host->fs[1].daddr.sin_port = htons(host->dport[1]+10);
	 */
	inet_ntop(AF_INET, &(host->fs[0].saddr.sin_addr), ipstr, INET_ADDRSTRLEN);
	vtun_syslog(LOG_INFO, " fd is %s:%d ->", ipstr,
			ntohs(host->fs[0].saddr.sin_port));
	inet_ntop(AF_INET, &(host->fs[0].daddr.sin_addr), ipstr, INET_ADDRSTRLEN);
	vtun_syslog(LOG_INFO, " fd is %s:%d <-", ipstr,
			ntohs(host->fs[0].daddr.sin_port));
	inet_ntop(AF_INET, &(host->fs[1].saddr.sin_addr), ipstr, INET_ADDRSTRLEN);
	vtun_syslog(LOG_INFO, " fd is %s:%d ->", ipstr,
			ntohs(host->fs[1].saddr.sin_port));
	inet_ntop(AF_INET, &(host->fs[1].daddr.sin_addr), ipstr, INET_ADDRSTRLEN);
	vtun_syslog(LOG_INFO, " fd is %s:%d <-", ipstr,
			ntohs(host->fs[1].daddr.sin_port));
	vtun_syslog(LOG_INFO, "UDP connection initialized");
	return s;
}
Пример #7
0
int fetch_server_data(struct vtun_host *host, int i, int j) {
	struct sockaddr_in saddr;
	short port;
	int s, opt;
	int buflen = 10;
	char buf[10];
	char ipstr[INET_ADDRSTRLEN];
	opt = sizeof(saddr);
	vtun_syslog(LOG_ERR, "Wait for response from client on Control");
	/*Wait for response from client on Control*/
	while (recvfrom(host->ctrl, (char *) &port, sizeof(short), 0,
			(struct sockaddr *) &saddr, &opt) <= 0)
		;

	inet_ntop(AF_INET, &(saddr.sin_addr), ipstr, INET_ADDRSTRLEN);
	vtun_syslog(LOG_INFO, "recvfrom %s:%d", ipstr, ntohs(saddr.sin_port));

	/*Open a UDP socket*/
	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
		vtun_syslog(LOG_ERR, "Can't create socket");
		return -1;
	}
	opt = 1;
	setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
	fcntl(s, F_SETFL, O_NONBLOCK);

	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(host->sport[i]);
	vtun_syslog(LOG_INFO, "trying to bind");
	vtun_syslog(LOG_INFO, "%d %s", i, host->saddr[i].ip);
	saddr.sin_addr.s_addr = inet_addr(host->saddr[i].ip);
	vtun_syslog(LOG_ERR, "Binding with %s", host->saddr[i].ip);
	/*Bind a port*/
	if (bind(s, (struct sockaddr *) &saddr, sizeof(saddr))) {
		vtun_syslog(LOG_ERR, "Can't bind to the socket");
		host->fs[i].fd_flag = 0;
		return -1;
	}
	host->fs[i].saddr = saddr;
	inet_ntop(AF_INET, &(host->fs[i].saddr.sin_addr), ipstr, INET_ADDRSTRLEN);
	vtun_syslog(LOG_INFO, "saddr %s:%d", ipstr, ntohs(saddr.sin_port));
	opt = sizeof(saddr);

	if (getsockname(s, (struct sockaddr *) &saddr, &opt)) {
		vtun_syslog(LOG_ERR, "Can't get socket name");
		return -1;
	}
	port = saddr.sin_port;

	vtun_syslog(LOG_ERR, "Send port number to Client on Control");
	/*Send port number to Client on Control*/
	opt = sizeof(host->fs[j].daddr);
	saddr = host->fs[j].daddr;
	saddr.sin_port = htons(host->ctrl_port);
	inet_ntop(AF_INET, &(saddr.sin_addr), ipstr, INET_ADDRSTRLEN);
	vtun_syslog(LOG_INFO, "%s:%d", ipstr, ntohs(saddr.sin_port));

	inet_ntop(AF_INET, &(host->fs[j].saddr.sin_addr), ipstr, INET_ADDRSTRLEN);
	vtun_syslog(LOG_INFO, "%s:%d", ipstr, ntohs(host->fs[j].saddr.sin_port));
	errno = 0;
	sendfromto(host->ctrl, (char *) &port, sizeof(short), 0,
			(struct sockaddr *) &host->fs[j].saddr, opt,
			(struct sockaddr *) &saddr, opt);

	/*Wait for PING on new Data Path*/
	vtun_syslog(LOG_ERR, "Wait for PING on new Control Path %s port %d",
			strerror(errno), port);
	while (recvfrom(s, (char *) &port, sizeof(short), 0,
			(struct sockaddr *) &saddr, &opt) <= 0)
		;
	host->fs[i].daddr = saddr;
	if (connect(s, (struct sockaddr *) &saddr, sizeof(saddr))) {
		vtun_syslog(LOG_ERR, "Can't connect socket");
		return -1;
	}
	host->fs[i].fd_flag = 1;
	host->fs[i].fd = s;
	port = 0;
	errno = 0;
	vtun_syslog(LOG_ERR, "Sent PONG on new Control Path");
	write_n(host->fs[i].fd, (char*) &port, sizeof(short));
	vtun_syslog(LOG_ERR, "WAIT PONG on new Control Path %s", strerror(errno));

	while (readn_t(host->fs[i].fd, (char*) &port, sizeof(short), host->timeout)
			< 0)
		;
	vtun_syslog(LOG_ERR, "%s", strerror(errno));
	/*SEND END_OF_REG*/
	return 0;
}
Пример #8
0
int fetch_control(struct vtun_host * host) {
	struct sockaddr_in saddr;
	short port;
	int s, opt;
	int buflen = 10;
	char buf[10];
	char ipstr[INET_ADDRSTRLEN];

	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
		vtun_syslog(LOG_ERR, "Can't create socket");
		return -1;
	}
	opt = 1;
	setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
	fcntl(s, F_SETFL, O_NONBLOCK);

	/* Set local address and port */
	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(host->ctrl_port);
	saddr.sin_addr.s_addr = htonl(INADDR_ANY);

	if (bind(s, (struct sockaddr *) &saddr, sizeof(saddr))) {
		vtun_syslog(LOG_ERR, "Can't bind to the socket");
		return -1;
	}

	opt = sizeof(saddr);
	if (getsockname(host->rmt_fd, (struct sockaddr *) &saddr, &opt)) {
		vtun_syslog(LOG_ERR, "Can't get socket name");
		return -1;
	}
	host->fs[0].saddr = saddr;

	if (getsockname(s, (struct sockaddr *) &saddr, &opt)) {
		vtun_syslog(LOG_ERR, "Can't get socket name");
		return -1;
	}

	/* if we are not just binding port number then we are server*/
	if (host->role == 1) {
		vtun_syslog(LOG_INFO, "udp_ctrl_session for server");

		/* Write port of the new UDP socket */
		port = saddr.sin_port;
		if (write_n(host->rmt_fd, (char *) &port, sizeof(short)) < 0) {
			vtun_syslog(LOG_ERR, "Can't write port number");
			return -1;
		}

		vtun_syslog(LOG_INFO, "Waiting for UDP ACK 1, wrote port %d", port);
		opt = sizeof(saddr);
		while (recvfrom(s, (char *) &port, sizeof(short), 0,
				(struct sockaddr *) &saddr, &opt) <= 0)
			;
		vtun_syslog(LOG_INFO, "UDP ACK 1 from  %s:%d",
				inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));

		host->fs[0].daddr.sin_family = saddr.sin_family;
		host->fs[0].daddr.sin_port = saddr.sin_port;
		host->fs[0].daddr.sin_addr.s_addr = saddr.sin_addr.s_addr;

		inet_ntop(AF_INET, &(host->fs[0].daddr.sin_addr), ipstr,
				INET_ADDRSTRLEN);
		vtun_syslog(LOG_INFO, "%s:%d", ipstr,
				ntohs(host->fs[0].daddr.sin_port));

		//sendto(s,(char *)&port,sizeof(short),0,(struct sockaddr *)&saddr,opt);
		errno = 0;
		sendfromto(s, (char *) &port, sizeof(short), 0,
				(struct sockaddr *) &host->fs[0].saddr, opt,
				(struct sockaddr *) &saddr, opt);

		vtun_syslog(LOG_INFO, "FINAL ACK SENT 1 %s", strerror(errno));
		inet_ntop(AF_INET, &(saddr.sin_addr), ipstr, INET_ADDRSTRLEN);
		vtun_syslog(LOG_INFO, "%s:%d", ipstr, ntohs(saddr.sin_port));
		host->ctrl_port = ntohs(saddr.sin_port);

	} else {

		//vtun_syslog(LOG_INFO,"udp_session for client 1");
		/* Read port of the other's end UDP socket */
		if (readn_t(host->rmt_fd, (char *) &port, sizeof(short), host->timeout)
				< 0) {
			vtun_syslog(LOG_ERR, "Can't read port number %s", strerror(errno));
			return -1;
		}
		vtun_syslog(LOG_INFO, "Recieved port %d info from server 1", port);
		opt = sizeof(saddr);
		if (getpeername(host->rmt_fd, (struct sockaddr *) &saddr, &opt)) {
			vtun_syslog(LOG_ERR, "Can't get peer name");
			return -1;
		}

		saddr.sin_port = port;

		inet_ntop(AF_INET, &(saddr.sin_addr), ipstr, INET_ADDRSTRLEN);
		vtun_syslog(LOG_INFO, "%s:%d", ipstr, ntohs(saddr.sin_port));
		inet_ntop(AF_INET, &(host->fs[0].saddr.sin_addr), ipstr,
				INET_ADDRSTRLEN);
		vtun_syslog(LOG_INFO, "%s:%d", ipstr,
				ntohs(host->fs[0].saddr.sin_port));
		errno = 0;
		sendfromto(s, (char *) &port, sizeof(short), 0,
				(struct sockaddr *) &host->fs[0].saddr, opt,
				(struct sockaddr *) &saddr, opt);
		vtun_syslog(LOG_INFO, "Sent ACK on UDP 1 :%s", strerror(errno));
		host->fs[0].daddr = saddr;
		while (recvfrom(s, (char *) &port, sizeof(short), 0,
				(struct sockaddr *) &saddr, &opt) <= 0)
			;
		vtun_syslog(LOG_INFO, "Connected & Recived final ACK 1");
		inet_ntop(AF_INET, &(saddr.sin_addr), ipstr, INET_ADDRSTRLEN);
		vtun_syslog(LOG_INFO, "%s:%d", ipstr, ntohs(saddr.sin_port));
		host->ctrl_port = ntohs(saddr.sin_port);

	}
	return s;
}
Пример #9
0
/* 
 * Establish UDP session with host connected to fd(socket).
 * Returns connected UDP socket or -1 on error.
 */
int udp_session(struct vtun_host *host) 
{
     struct sockaddr_in saddr; 
     short port;
     int s,opt;

     if( (s=socket(AF_INET,SOCK_DGRAM,0))== -1 ){
        vtun_syslog(LOG_ERR,"Can't create socket");
        return -1;
     }

     opt=1;
     setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); 
    
     /* Set local address and port */
     local_addr(&saddr, host, 1);
     if( bind(s,(struct sockaddr *)&saddr,sizeof(saddr)) ){
        vtun_syslog(LOG_ERR,"Can't bind to the socket");
        return -1;
     }

     opt = sizeof(saddr);
     if( getsockname(s,(struct sockaddr *)&saddr,&opt) ){
        vtun_syslog(LOG_ERR,"Can't get socket name");
        return -1;
     }

     /* Write port of the new UDP socket */
     port = saddr.sin_port;
     if( write_n(host->rmt_fd,(char *)&port,sizeof(short)) < 0 ){
        vtun_syslog(LOG_ERR,"Can't write port number");
        return -1;
     }
     host->sopt.lport = htons(port);

     /* Read port of the other's end UDP socket */
     if( readn_t(host->rmt_fd,&port,sizeof(short),host->timeout) < 0 ){
        vtun_syslog(LOG_ERR,"Can't read port number %s", strerror(errno));
        return -1;
     }

     opt = sizeof(saddr);
     if( getpeername(host->rmt_fd,(struct sockaddr *)&saddr,&opt) ){
        vtun_syslog(LOG_ERR,"Can't get peer name");
        return -1;
     }

     saddr.sin_port = port;
     if( connect(s,(struct sockaddr *)&saddr,sizeof(saddr)) ){
        vtun_syslog(LOG_ERR,"Can't connect socket");
        return -1;
     }
     host->sopt.rport = htons(port);

     /* Close TCP socket and replace with UDP socket */	
     close(host->rmt_fd); 
     host->rmt_fd = s;	

     vtun_syslog(LOG_INFO,"UDP connection initialized");
     return s;
}