Example #1
0
int alloc_lzo(struct vtun_host *host)
{
     int zlevel = host->zlevel ? host->zlevel : 1;
     int mem;

     switch( zlevel ){
	case 9:
	   lzo1x_compress = lzo1x_999_compress;
           mem = LZO1X_999_MEM_COMPRESS;
           break;
	default: 	   
 	   lzo1x_compress = lzo1x_1_15_compress;
           mem = LZO1X_1_15_MEM_COMPRESS;
           break;
     }

     if( lzo_init() != LZO_E_OK ){
	vtun_syslog(LOG_ERR,"Can't initialize compressor");
	return 1;
     }	
     if( !(zbuf = lfd_alloc(zbuf_size)) ){
	vtun_syslog(LOG_ERR,"Can't allocate buffer for the compressor");
	return 1;
     }	
     if( !(wmem = lzo_malloc(mem)) ){
	vtun_syslog(LOG_ERR,"Can't allocate buffer for the compressor");
	return 1;
     }	

     vtun_syslog(LOG_INFO, "LZO compression[level %d] initialized", zlevel);

     return 0;
}
Example #2
0
void server(int sock)
{
     struct sigaction sa;

     sa.sa_handler=SIG_IGN;
     sa.sa_flags=SA_NOCLDWAIT;;
     sigaction(SIGINT,&sa,NULL);
     sigaction(SIGQUIT,&sa,NULL);
     sigaction(SIGCHLD,&sa,NULL);
     sigaction(SIGPIPE,&sa,NULL);
     sigaction(SIGUSR1,&sa,NULL);

     vtun_syslog(LOG_INFO,"VTUN server ver %s (%s)", VTUN_VER,
		 vtun.svr_type == VTUN_INETD ? "inetd" : "stand" );

     switch( vtun.svr_type ){
	case VTUN_STAND_ALONE:
#ifdef HAVE_WORKING_FORK
	   listener();
#else
	   vtun_syslog(LOG_ERR,"Standalone server is not supported: fork() not available");
#endif
	   break;
        case VTUN_INETD:
	   connection(sock);
	   break;
     }    
}
Example #3
0
int zlib_decomp(int len, char *in, char **out)
{
     int oavail = 0, olen = 0;     
     int err;

     zi.next_in = (void *) in;
     zi.avail_in = len;
     zi.next_out = (void *) zbuf;
     zi.avail_out = zbuf_size;

     while(1) {
        oavail = zi.avail_out;
        if( (err=inflate(&zi, Z_SYNC_FLUSH)) != Z_OK ) {
           vtun_syslog(LOG_ERR,"Inflate error %d len %d", err, len);
           return -1;
        }
        olen += oavail - zi.avail_out;
        if(!zi.avail_in)
	   break;
        if( expand_zbuf(&zi,100) ) {
	   vtun_syslog( LOG_ERR, "Can't expand compression buffer");
           return -1;
	}
     }
     *out = (void *) zbuf;
     return olen;
}
Example #4
0
/* 
 * Initialize compressor/decompressor.
 * Allocate the buffer.
 */  
int zlib_alloc(struct vtun_host *host)
{
     int zlevel = host->zlevel ? host->zlevel : 1;

     zd.zalloc = (alloc_func)0;
     zd.zfree  = (free_func)0;
     zd.opaque = (voidpf)0;
     zi.zalloc = (alloc_func)0;
     zi.zfree  = (free_func)0;
     zi.opaque = (voidpf)0;
    
     if( deflateInit(&zd, zlevel ) != Z_OK ){
	vtun_syslog(LOG_ERR,"Can't initialize compressor");
	return 1;
     }	
     if( inflateInit(&zi) != Z_OK ){
	vtun_syslog(LOG_ERR,"Can't initialize decompressor");
	return 1;
     }	
     if( !(zbuf = (void *) lfd_alloc(zbuf_size)) ){
	vtun_syslog(LOG_ERR,"Can't allocate buffer for the compressor");
	return 1;
     }
   
     vtun_syslog(LOG_INFO,"ZLIB compression[level %d] initialized.", zlevel);
     return 0;
}
Example #5
0
/* Set address by interface name, ip address or hostname */
int generic_addr(struct sockaddr_in *addr, struct vtun_addr *vaddr)
{
    struct hostent *hent;
    memset(addr, 0, sizeof(struct sockaddr_in));

    addr->sin_family = AF_INET;

    switch (vaddr->type) {
    case VTUN_ADDR_IFACE:
	if (!(addr->sin_addr.s_addr = getifaddr(vaddr->name))) {
	    vtun_syslog(LOG_ERR,
			"Can't get address of interface %s", vaddr->name);
	    return -1;
	}
	break;
    case VTUN_ADDR_NAME:
	if (!(hent = gethostbyname(vaddr->name))) {
	    vtun_syslog(LOG_ERR,
			"Can't resolv local address %s", vaddr->name);
	    return -1;
	}
	addr->sin_addr.s_addr = *(unsigned long *) hent->h_addr;
	break;
    default:
	addr->sin_addr.s_addr = INADDR_ANY;
	break;
    }

    if (vaddr->port)
	addr->sin_port = htons(vaddr->port);

    return 0;
}
Example #6
0
void connection(int sock)
{
     struct sockaddr_in my_addr, cl_addr;
     struct vtun_host *host;
     struct sigaction sa;
     char *ip;
     int opt;

     opt = sizeof(struct sockaddr_in);
     if( getpeername(sock, (struct sockaddr *) &cl_addr, &opt) ){
        vtun_syslog(LOG_ERR, "Can't get peer name");
        exit(1);
     }
     opt = sizeof(struct sockaddr_in);
     if( getsockname(sock, (struct sockaddr *) &my_addr, &opt) < 0 ){
        vtun_syslog(LOG_ERR, "Can't get local socket address");
        exit(1); 
     }

     ip = strdup(inet_ntoa(cl_addr.sin_addr));

     io_init();

     if( (host=auth_server(sock)) ){	
        sa.sa_handler=SIG_IGN;
	sa.sa_flags=SA_NOCLDWAIT;;
        sigaction(SIGHUP,&sa,NULL);

	vtun_syslog(LOG_INFO,"Session %s[%s:%d] opened", host->host, ip, 
					ntohs(cl_addr.sin_port) );
        host->rmt_fd = sock; 
	
        host->sopt.laddr = strdup(inet_ntoa(my_addr.sin_addr));
        host->sopt.lport = vtun.bind_addr.port;
        host->sopt.raddr = strdup(ip);
	host->sopt.rport = ntohs(cl_addr.sin_port);

	/* Start tunnel */
	tunnel(host, 1);

	vtun_syslog(LOG_INFO,"Session %s closed", host->host);

	/* Unlock host. (locked in auth_server) */	
	unlock_host(host);
     } else {
        vtun_syslog(LOG_INFO,"Denied connection from %s:%d", ip,
					ntohs(cl_addr.sin_port) );
     }
     close(sock);

     exit(0);
}
Example #7
0
int run_cmd(void *d, void *opt)
{
     struct vtun_cmd *cmd = d;	
     char *argv[50], *args;
     int pid, st;

     switch( (pid=fork()) ){
	case 0:
	   break;
	case -1:
	   vtun_syslog(LOG_ERR,"Couldn't fork()");
	   return 0;
	default:
    	   if( cmd->flags & VTUN_CMD_WAIT ){
	      /* Wait for termination */
	      if( waitpid(pid,&st,0) > 0 && (WIFEXITED(st) && WEXITSTATUS(st)) )
		 vtun_syslog(LOG_INFO,"Command [%s %.20s] error %d", 
				cmd->prog ? cmd->prog : "sh",
				cmd->args ? cmd->args : "", 
				WEXITSTATUS(st) );
	   }
    	   if( cmd->flags & VTUN_CMD_DELAY ){
	      struct timespec tm = { VTUN_DELAY_SEC, 0 };
	      /* Small delay hack to sleep after pppd start.
	       * Until I have no good solution for solving 
	       * PPP + route problem  */
	      nanosleep(&tm, NULL);
	   }
	   return 0;	 
     }

     args = subst_opt(cmd->args, opt);
     if( !cmd->prog ){
	/* Run using shell */
	cmd->prog = "/bin/sh";
        argv[0] = "sh";	
	argv[1] = "-c";
	argv[2] = args;
	argv[3] = NULL;
     } else {
        argv[0] = cmd->prog;	
        split_args(args, argv + 1);
     }
     execv(cmd->prog, argv);

     vtun_syslog(LOG_ERR,"Couldn't exec program %s", cmd->prog);
     exit(1);
}
Example #8
0
void server(int sock)
{
     struct sigaction sa;

     sa.sa_handler=SIG_IGN;
     sa.sa_flags=SA_NOCLDWAIT;;
     sigaction(SIGINT,&sa,NULL);
     sigaction(SIGQUIT,&sa,NULL);
     sigaction(SIGCHLD,&sa,NULL);
     sigaction(SIGPIPE,&sa,NULL);
     sigaction(SIGUSR1,&sa,NULL);
     sigaction(SIGUSR2,&sa,NULL);

     vtun_syslog(LOG_INFO,"vtrunkd server ver %s %s (%s)", VTUN_VER, BUILD_DATE,
		 vtun.svr_type == VTUN_INETD ? "inetd" : "stand" );

     switch( vtun.svr_type ){
	case VTUN_STAND_ALONE:
	   listener();
	   break;
        case VTUN_INETD:
	   connection(sock);
	   break;
     }    
}
Example #9
0
void reread_config(int sig)
{
     if( !read_config(vtun.cfg_file) ){
	vtun_syslog(LOG_ERR,"No hosts defined");
	exit(1);
     }
}
Example #10
0
int send_new_port(struct vtun_host *host, int i, int j, int ctrl_msg_type) {
	struct sockaddr_in saddr;
	short port;
	int s, opt;
	int buflen = 10;
	char buf[10];
	char ipstr[INET_ADDRSTRLEN];
	ctrl_msg cm;
	bind_link bl;

	vtun_syslog(LOG_ERR, "send_new_port creating socket for %d using %d", i, j);
	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]);
	saddr.sin_addr.s_addr = inet_addr(host->saddr[i].ip);

	//vtun_syslog(LOG_ERR,"send_new_port bind to port");
	errno = 0;
	/*Bind a port*/
	if (bind(s, (struct sockaddr *) &saddr, sizeof(saddr))) {
		vtun_syslog(LOG_ERR, "Can't bind to the socket");
		return -1;
	}

	opt = sizeof(saddr);

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

	opt = sizeof(host->fs[j].daddr);
	cm.type = ctrl_msg_type;
	bl.index = i;
	bl.port = port;
	cm.bl = bl;

	// vtun_syslog(LOG_ERR,"send_new_port sending");
	errno = 0;
	sendfromto(host->ctrl, (char *) &cm, sizeof(cm), 0,
			(struct sockaddr *) &host->fs[j].saddr, opt,
			(struct sockaddr *) &host->fs[j].daddr, opt);
	inet_ntop(AF_INET, &(host->fs[j].saddr.sin_addr), ipstr, INET_ADDRSTRLEN);
	vtun_syslog(LOG_INFO, "From %s:%d", ipstr,
			ntohs(host->fs[j].saddr.sin_port));
	inet_ntop(AF_INET, &(host->fs[j].daddr.sin_addr), ipstr, INET_ADDRSTRLEN);
	vtun_syslog(LOG_INFO, "To %s:%d", ipstr, ntohs(host->fs[j].daddr.sin_port));
	vtun_syslog(LOG_ERR, "send_new_port returning %s", strerror(errno));

	return 1;
}
Example #11
0
File: main.c Project: spillay/BSOL
/* 
 * Very simple PID file creation function. Used by server.
 * Overrides existing file. 
 */
void write_pid(void) {
	FILE *f;

	if (!(f = fopen(VTUN_PID_FILE, "w"))) {
		vtun_syslog(LOG_ERR, "Can't write PID file");
		return;
	}

	fprintf(f, "%d", (int) getpid());
	fclose(f);
}
Example #12
0
int decomp_lzo(int len, char *in, char **out)
{
     unsigned int zlen = 0;
     int err;

     if( (err=lzo1x_decompress((void *)in,len,zbuf,&zlen,wmem)) != LZO_E_OK ){
        vtun_syslog(LOG_ERR,"Decompress error %d",err);
        return -1;
     }

     *out = (void *) zbuf;
     return zlen;
}
Example #13
0
int prep_key(char **key, int size, struct vtun_host *host)
{
   int tmplen, halflen;
   char *hashkey;

   if ( !(hashkey = malloc(size)) )
   {
      vtun_syslog(LOG_ERR,"Can't allocate buffer for key hash");
      return -1;
   }
   memset(hashkey,0,size);

   if (size == 32)
   {
      tmplen = strlen(host->passwd);
      if (tmplen != 0) halflen = tmplen>>1;
      else halflen = 0;
Example #14
0
void send_flag_info(struct vtun_host *host, int ctrl) {
	ctrl_msg cm;
	fd_info my_info;
	int i;

	cm.type = FD_INFO;
	for (i = 0; i < VTUN_MAX_INT; i++) {
		my_info.flag[i] = host->fs[i].fd_flag;
	}
	cm.fi = my_info;
	i = sizeof(host->fs[ctrl].daddr);

	sendfromto(host->ctrl, (char *) &cm, sizeof(cm), 0,
			(struct sockaddr *) &host->fs[ctrl].saddr, i,
			(struct sockaddr *) &host->fs[ctrl].daddr, i);
	vtun_syslog(-1, "FLAG INFO IS SENT ");

}
Example #15
0
/* Set local address */
int local_addr(struct sockaddr_in *addr, struct vtun_host *host, int con) {
	int opt;

	if (con) {
		/* Use address of the already connected socket. */
		opt = sizeof(struct sockaddr_in);
		if (getsockname(host->rmt_fd, (struct sockaddr *) addr, &opt) < 0) {
			vtun_syslog(LOG_ERR, "Can't get local socket address");
			return -1;
		}
	} else {
		if (generic_addr(addr, &host->src_addr) < 0)
			return -1;
	}

	host->sopt.laddr = strdup(inet_ntoa(addr->sin_addr));

	return 0;
}
Example #16
0
void send_unbind_req(struct vtun_host *host, int index) {
	ctrl_msg cm;
	bind_link bl;
	int i;
	int j;
	int opt;
	cm.type = UNBIND_REQ;
	bl.index = index;
	bl.port = 0;
	cm.bl = bl;
	j = get_ctrl_index(host);

	opt = sizeof(host->fs[j].daddr);

	sendfromto(host->ctrl, (char *) &cm, sizeof(cm), 0,
			(struct sockaddr *) &host->fs[j].saddr, opt,
			(struct sockaddr *) &host->fs[j].daddr, opt);
	close(host->fs[index].fd);
	vtun_syslog(LOG_ERR, "UNBIND REQ IS SENT %d", index);
	return;
}
Example #17
0
int server_addr(struct sockaddr_in *addr, struct vtun_host *host) {
	struct hostent * hent;

	memset(addr, 0, sizeof(struct sockaddr_in));
	addr->sin_family = AF_INET;
	addr->sin_port = htons(vtun.bind_addr.port);

	/* Lookup server's IP address.
	 * We do it on every reconnect because server's IP
	 * address can be dynamic.
	 */
	if (!(hent = gethostbyname(vtun.svr_name))) {
		vtun_syslog(LOG_ERR, "Can't resolv server address: %s", vtun.svr_name);
		return -1;
	}
	addr->sin_addr.s_addr = *(unsigned long *) hent->h_addr;

	host->sopt.raddr = strdup(inet_ntoa(addr->sin_addr));
	host->sopt.rport = vtun.bind_addr.port;

	return 0;
}
Example #18
0
int udp_session_fs(struct vtun_host *host, int count) {
	struct sockaddr_in saddr;
	short port;
	int s, opt;
	saddr.sin_family = AF_INET;
	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
		vtun_syslog(LOG_ERR, "Can't create socket %d", count);
		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[count];
	saddr.sin_addr.s_addr = inet_addr(host->saddr[count].ip);

	vtun_syslog(LOG_ERR, "address %s:%d", host->saddr[count].ip,
			host->sport[count]);
	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 socket (%d:%s)", errno,
				strerror(errno));
		return -1;
	}

	saddr.sin_port = host->dport[count];
	saddr.sin_addr.s_addr = inet_addr(host->daddr[count].ip);
	if (connect(s, (struct sockaddr *) &saddr, sizeof(saddr))) {
		vtun_syslog(LOG_ERR, "Can't connect socket %d ", count);
		return -1;
	}
	host->fs[count].saddr = saddr;
	host->fs[count].fd = s;
	host->fs[count].fd_flag = 1;

	vtun_syslog(LOG_INFO, "UDP %d connection initialized", count);
	return s;
}
Example #19
0
/*
int cshit3(struct conn_info * sci, int fx) {
     int cnt = 0, cnt2=0;
     int nnl = sci->resend_buf.frames.rel_head;
     int nnf = sci->resend_buf.free_frames.rel_head;
     
     while(nnl > -1) {
          cnt++;
          nnl = sci->resend_buf.frames_buf[nnl].rel_next;
     }
     
     while(nnf > -1) {
          cnt++;
          nnf = sci->resend_buf.frames_buf[nnf].rel_next;
     }
     vtun_syslog(LOG_INFO, "%d count l: %d f: %d", fx, cnt, cnt2);
     return 0;
}
 */
void client(struct vtun_host *host)
{
     struct sockaddr_in my_addr,svr_addr;
     struct sigaction sa;
     int s, opt, reconnect, sss, len;
     int shm_new = 0;
     struct sockaddr_un remote;

     vtun_syslog(LOG_INFO,"vtrunkd client ver %s %s started",VTUN_VER, BUILD_DATE);

     memset(&sa,0,sizeof(sa));     
     sa.sa_handler=SIG_IGN;
     sa.sa_flags = SA_NOCLDWAIT;
     sigaction(SIGHUP,&sa,NULL);
     sigaction(SIGQUIT,&sa,NULL);
     sigaction(SIGPIPE,&sa,NULL);
     sigaction(SIGCHLD,&sa,NULL);

     sa.sa_handler=sig_term;
     sigaction(SIGTERM,&sa,NULL);
     sigaction(SIGINT,&sa,NULL);
     
     
     // now init everything...
     int shmid;
     key_t key;
     struct conn_info *shm_conn_info;
     struct timeval cur_time;
     /*
     * We'll name our shared memory segment
     * "5678".
     */
     key = SHM_TUN_KEY;
     

      /*
      * First, try to open shm
      */
     
     if ((shmid = shmget(key, sizeof(struct conn_info), 0666)) < 0) {
          /*
          * Create the segment.
          */
          vtun_syslog(LOG_INFO,"client: init new shm...");
          if ((shmid = shmget(key, sizeof(struct conn_info), IPC_CREAT | 0666)) < 0) {
             vtun_syslog(LOG_ERR,"shmget 2 size %d", sizeof(struct conn_info));
             exit(1);
          }
          shm_new = 1;
     } else {
          vtun_syslog(LOG_INFO,"client: reusing shm...");
          shm_new = 0;
     }
     /*
     * Now we attach the segment to our data space.
     */
     if ((shm_conn_info = shmat(shmid, NULL, 0)) == (struct conn_info *) -1) {
        vtun_syslog(LOG_ERR,"shmat 2");
        exit(1);
     }
     //cshit3(&shm_conn_info[0], 36);
     // now try to connect to socket if shm_new ==0
     if(!shm_new) {
                    if ((sss = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
                         vtun_syslog(LOG_ERR, "socket 44");
                         exit(1);
                    }
                    remote.sun_family = AF_UNIX;
                    strcpy(remote.sun_path, shm_conn_info[0].devname);
                    len = strlen(remote.sun_path) + sizeof(remote.sun_family);
                    if ( (shm_conn_info->rdy) && (connect(sss, (struct sockaddr *)&remote, len) == -1)) {
                         vtun_syslog(LOG_INFO, "SHM ready but socket not open! Assuming we're only process running;");
                         shm_new = 1; // could not connect; assume we're new!
                    } else {
                         vtun_syslog(LOG_INFO, "Socket connected OK seems all OK");
                    }
                    close(sss);
     }
     if(shm_new) {
          vtun_syslog(LOG_INFO, "client doing memset");
          memset(shm_conn_info, 0, sizeof(struct conn_info));
     }
     //cshit3(&shm_conn_info[0], 37);
     
     client_term = 0; reconnect = 0;
     while( (!client_term) || (client_term == VTUN_SIG_HUP) ){
	if( reconnect && (client_term != VTUN_SIG_HUP) ){
	   if( vtun.persist || host->persist ){
	      /* Persist mode. Sleep and reconnect. */
	      sleep(5);
           } else {
	      /* Exit */
	      break;
	   }
	} else {
	   reconnect = 1;
        }

	set_title("%s init initializing", host->host);

	/* Set server address */
        if( server_addr(&svr_addr, host) < 0 )
	   continue;

	/* Set local address */
	if( local_addr(&my_addr, host, 0) < 0 )
	   continue;

	/* We have to create socket again every time
	 * we want to connect, since STREAM sockets 
	 * can be successfully connected only once.
	 */
        if( (s = socket(AF_INET,SOCK_STREAM,0))==-1 ){
	   vtun_syslog(LOG_ERR,"Can't create socket. %s(%d)", 
		strerror(errno), errno);
	   continue;
        }
        //cshit3(&shm_conn_info[0], 38);

	/* Required when client is forced to bind to specific port */
        opt=1;
        setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
        
        #ifndef W_O_SO_MARK
        if(host->RT_MARK != -1) {
               if (setsockopt(s, SOL_SOCKET, SO_MARK, &host->RT_MARK, sizeof(host->RT_MARK))) {
                   vtun_syslog(LOG_ERR,"client socket rt mark error %s(%d)",
                              strerror(errno), errno);
                   break;
               }
        }
        #endif


        if( bind(s,(struct sockaddr *)&my_addr,sizeof(my_addr)) ){
	   vtun_syslog(LOG_ERR,"Can't bind socket. %s(%d)",
		strerror(errno), errno);
	   continue;
        }

        /* 
         * Clear speed and flags which will be supplied by server. 
         */
        host->spd_in = host->spd_out = 0;
        host->flags &= VTUN_CLNT_MASK;

	io_init();

	set_title("%s connecting to %s", host->host, vtun.svr_name);
        vtun_syslog(LOG_INFO,"Connecting to %s", vtun.svr_name);

        if( connect_t(s,(struct sockaddr *) &svr_addr, host->timeout) ){
	   vtun_syslog(LOG_INFO,"Connect to %s failed. %s(%d)", vtun.svr_name,
					strerror(errno), errno);
        } else {
	   if( auth_client(s, host) ){   
	      vtun_syslog(LOG_INFO,"Session %s[%s] opened",host->host,vtun.svr_name);
              


 	      host->rmt_fd = s;
              //cshit3(&shm_conn_info[0], 39);

	      /* Start the tunnel */
	      client_term = tunnel(host, 0);
              gettimeofday(&cur_time, NULL);
              shm_conn_info->alive = cur_time.tv_sec; // show we are alive and trying to reconnect still.. (or fd_server will quit)

	      vtun_syslog(LOG_INFO,"Session %s[%s] closed",host->host,vtun.svr_name);
	   } else {
	      vtun_syslog(LOG_INFO,"Connection denied by %s",vtun.svr_name);
	   }
	}
	close(s);
	free_sopt(&host->sopt);
     }

     vtun_syslog(LOG_INFO, "Exit");
     return;
}
Example #20
0
void listener(void)
{
     struct sigaction sa;
     struct sockaddr_in my_addr, cl_addr;
     int s, s1, opt;

     memset(&my_addr, 0, sizeof(my_addr));
     my_addr.sin_family = AF_INET;

     /* Set listen address */
     if( generic_addr(&my_addr, &vtun.bind_addr) < 0)
     {
        vtun_syslog(LOG_ERR, "Can't fill in listen socket");
        exit(1);
     }

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

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

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

     if( listen(s, 10) ){
	vtun_syslog(LOG_ERR,"Can't listen on the socket");
	exit(1);
     }

     memset(&sa,0,sizeof(sa));
     sa.sa_flags = SA_NOCLDWAIT;
     sa.sa_handler=sig_term;
     sigaction(SIGTERM,&sa,NULL);
     sigaction(SIGINT,&sa,NULL);
     // WARNING: signals should be re-checked before using!
     server_term = 0;

     set_title("waiting for connections on port %d", vtun.bind_addr.port);
     
     // now init everything...
     int shmid;
     key_t key;
     struct conn_info* shm_conn_info;
     /*
     * We'll name our shared memory segment
     * "5678".
     */
     key = SHM_TUN_KEY;
     
     /*
     * Create the segment.
     */
     // TODO: do not allocate all memory at once!!!!
     if ((shmid = shmget(key, sizeof(struct conn_info) * vtun.MAX_TUNNELS_NUM, IPC_CREAT | 0666)) < 0) {
        vtun_syslog(LOG_ERR,"Can not allocate SHM buffer of size %d. Please check your system shmmax or use 'ipcrm' to remove stale SHMs", sizeof(struct conn_info) * vtun.MAX_TUNNELS_NUM);
        exit(1);
     }
     
     /*
     * Now we attach the segment to our data space.
     */
     if ((shm_conn_info = shmat(shmid, NULL, 0)) == (struct conn_info *) -1) {
        vtun_syslog(LOG_ERR,"shmat 1");
        exit(1);
     }
     
     memset(shm_conn_info, 0, sizeof(struct conn_info) * vtun.MAX_TUNNELS_NUM);

     while( (!server_term) || (server_term == VTUN_SIG_HUP) ){
        opt=sizeof(cl_addr);
	if( (s1=accept(s,(struct sockaddr *)&cl_addr,&opt)) < 0 )
	   continue; 

	switch( fork() ){
	   case 0:
	      close(s);
#ifdef DEBUGG
               // now init the profiler; don;t forget to set GMON_OUT_PREFIX
               extern void _start (void), etext (void);
               monstartup ((u_long) &_start, (u_long) &etext);
#endif
	      connection(s1);
	      break;
	   case -1:
	      vtun_syslog(LOG_ERR, "Couldn't fork()");
	   default:
	      close(s1);
              // normal cont
	      break;
	}
     }
     
     shmctl(key, IPC_RMID, NULL);
     
     vtun_syslog(LOG_INFO, "SERVER QUIT %d", server_term);
}	
Example #21
0
int cf2bf(char *str, struct vtun_host *host)
{
     char *ptr, *p;
     int s;

     if( (ptr = strchr(str,'<')) ){ 
	vtun_syslog(LOG_DEBUG,"Remote Server sends %s.", ptr);
	ptr++;
	while(*ptr){  
	   switch(*ptr++){
	     case 't':
		host->flags |= VTUN_TTY;
		break;
	     case 'p':
		host->flags |= VTUN_PIPE;
		break;
	     case 'e':
		host->flags |= VTUN_ETHER;
		break;
	     case 'u':
		host->flags |= VTUN_TUN;
		break;
	     case 'U':
		host->flags &= ~VTUN_PROT_MASK;
		host->flags |= VTUN_UDP;
		break;
	     case 'X':
		host->flags &= ~VTUN_PROT_MASK;
		host->flags |= VTUN_SCTP;
		break;
	     case 'T':
		host->flags &= ~VTUN_PROT_MASK;
		host->flags |= VTUN_TCP;
		break;
	     case 'K':
		host->flags |= VTUN_KEEP_ALIVE;
		break;
	     case 'C':
		if((s = strtol(ptr,&p,10)) == ERANGE || ptr == p) 
		   return 0;
		host->flags |= VTUN_ZLIB;
		host->zlevel = s; 
		ptr = p;
		break;
	     case 'L':
		if((s = strtol(ptr,&p,10)) == ERANGE || ptr == p) 
		   return 0;
		host->flags |= VTUN_LZO;
		host->zlevel = s; 
		ptr = p;
		break;
	     case 'E':
	        /* new form is 'E10', old form is 'E', so remove the
		   ptr==p check */
		if((s = strtol(ptr,&p,10)) == ERANGE) {
		   vtun_syslog(LOG_ERR,"Garbled encryption method.  Bailing out.");
		   return 0;
		}
		host->flags |= VTUN_ENCRYPT;
		if (0 == s) {
		   host->cipher = VTUN_LEGACY_ENCRYPT;
		   vtun_syslog(LOG_INFO,"Remote server using older encryption.");
		} else {
		   host->cipher = s; 
		}
		ptr = p;
		break;
     	     case 'S':
		if((s = strtol(ptr,&p,10)) == ERANGE || ptr == p) 
		   return 0;
		if( s ){
	    	   host->flags |= VTUN_SHAPE;
		   host->spd_out = s; 
		}
		ptr = p;
		break;
	     case 'F':
	        /* reserved for Feature transmit */
	       break;
	     case '>':
	        return 1;
	     default:
		return 0;
	   }
	}
     }
     return 0;
}
Example #22
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;
}
Example #23
0
int no_zlib(struct vtun_host *host)
{
     vtun_syslog(LOG_INFO, "ZLIB compression is not supported");
     return -1;
}
Example #24
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;
}
Example #25
0
int main(int argc, char *argv[], char *env[])
{
  int svr, daemon, sock, dofork, fd, opt;
     struct vtun_host *host = NULL;
     struct sigaction sa;
     char *hst;

     /* Configure default settings */
     svr = 0; daemon = 1; sock = 0; dofork = 1;

     vtun.cfg_file = VTUN_CONFIG_FILE;
     vtun.persist = -1;
     vtun.timeout = -1;
	
     /* Dup strings because parser will try to free them */
     vtun.ppp   = strdup("/usr/sbin/pppd");
     vtun.ifcfg = strdup("/sbin/ifconfig");
     vtun.route = strdup("/sbin/route");
     vtun.fwall = strdup("/sbin/ipchains");	
     vtun.iproute = strdup("/sbin/ip");	

     vtun.svr_name = NULL;
     vtun.svr_addr = NULL;
     vtun.bind_addr.port = -1;
     vtun.svr_type = -1;
     vtun.syslog   = LOG_DAEMON;

     /* Initialize default host options */
     memset(&default_host, 0, sizeof(default_host));
     default_host.flags   = VTUN_TTY | VTUN_TCP|VTUN_SCTP;
     default_host.multi   = VTUN_MULTI_ALLOW;
     default_host.timeout = VTUN_CONNECT_TIMEOUT;
     default_host.ka_interval = 30;
     default_host.ka_maxfail  = 4;
     default_host.loc_fd = default_host.rmt_fd = -1;

     /* Start logging to syslog and stderr */
     openlog("vtund", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON);

     while( (opt=getopt(argc,argv,"misf:P:L:t:npq")) != EOF ){
	switch(opt){
	    case 'm':
	        if (mlockall(MCL_CURRENT | MCL_FUTURE) < 0) {
		    perror("Unable to mlockall()");
		    exit(-1);
	        }
		break;
	    case 'i':
		vtun.svr_type = VTUN_INETD;
	    case 's':
		svr = 1;
		break;
	    case 'L':
		vtun.svr_addr = strdup(optarg);
		break;
	    case 'P':
		vtun.bind_addr.port = atoi(optarg);
		break;
	    case 'f':
		vtun.cfg_file = strdup(optarg);
		break;
	    case 'n':
		daemon = 0;
		break;
	    case 'p':
		vtun.persist = 1;
		break;
	    case 't':
	        vtun.timeout = atoi(optarg);	
	        break;
	    case 'q':
		vtun.quiet = 1;
		break;
	    default:
		usage();
	        exit(1);
	}
     }	
     reread_config(0);

     if (vtun.syslog != LOG_DAEMON) {
	/* Restart logging to syslog using specified facility  */
 	closelog();
 	openlog("vtund", LOG_PID|LOG_NDELAY|LOG_PERROR, vtun.syslog);
     }

	clear_nat_hack_flags(svr);

     if(!svr){
	if( argc - optind < 2 ){
	   usage();
           exit(1);
	}
	hst = argv[optind++];

        if( !(host = find_host(hst)) ){	
	   vtun_syslog(LOG_ERR,"Host %s not found in %s", hst, vtun.cfg_file);
	   exit(1);
        }

	vtun.svr_name = strdup(argv[optind]);
     } 
      	
     /* 
      * Now fill uninitialized fields of the options structure
      * with default values. 
      */ 
     if(vtun.bind_addr.port == -1)
	vtun.bind_addr.port = VTUN_PORT;
     if(vtun.persist == -1)
	vtun.persist = 0;
     if(vtun.timeout == -1)
	vtun.timeout = VTUN_TIMEOUT;

     switch( vtun.svr_type ){
	case -1:
	   vtun.svr_type = VTUN_STAND_ALONE;
	   break;
	case VTUN_INETD:
	   sock = dup(0);
	   dofork = 0; 
	   break;
     }

     if( daemon ){
	if( dofork && fork() )
	   exit(0);

        /* Direct stdin,stdout,stderr to '/dev/null' */
        fd = open("/dev/null", O_RDWR);
	close(0); dup(fd);
	close(1); dup(fd);
        close(2); dup(fd);
        close(fd);

	setsid();

	chdir("/");
     }

     if(svr){
        memset(&sa,0,sizeof(sa));     
        sa.sa_handler=reread_config;
        sigaction(SIGHUP,&sa,NULL);

        init_title(argc,argv,env,"vtund[s]: ");

	if( vtun.svr_type == VTUN_STAND_ALONE )	
	   write_pid();
	
	runmode=1;
	server(sock);
     } else {	
        init_title(argc,argv,env,"vtund[c]: ");
	runmode=0;
        client(host);
     }

     closelog();
	
     return 0;
}
Example #26
0
int sctp_session(struct vtun_host *host)
{
    extern int runmode;
    int s, opt, newfd, i;
	int len;
    short port;
    struct sockaddr_in saddr, caddr;
    struct addrinfo hints, *srvinfo, *p;
    memset(&hints, 0, sizeof hints);
    memset(&caddr, 0, sizeof caddr);
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_SCTP;

	len=0;
    vtun_syslog(LOG_ERR, "进入sctp");
    if (runmode == 1) {
	//server
	vtun_syslog(LOG_ERR, "进入server");
	hints.ai_flags = AI_PASSIVE;

	i = getaddrinfo(NULL, "9000", &hints, &srvinfo);
	if (i < 0) {
	    fprintf(stderr, "getaddrinfo %s\n", gai_strerror(i));
	    return -1;
	}

	for (p = srvinfo; p != NULL; p = p->ai_next) {
	    s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
	    if (s < 0)
		continue;
	    i = bind(s, p->ai_addr, p->ai_addrlen);
	    if (i == 0)
		break;
	}
	if (p == NULL) {
	    perror("bind 失败\n");
	    return -1;
	}

	i = listen(s, 10);
	if (i < 0) {
	    perror("listen 失败\n");
	    return -1;
	}

	 vtun_syslog(LOG_ERR, "等待客户端连接...");
	newfd = accept(s, (struct sockaddr *) &caddr, &len);
	if (newfd < 0) {
	    vtun_syslog(LOG_ERR, "不能接受客户端链接!!");
	    return -1;
	}

	 vtun_syslog(LOG_ERR, "切换fd");

	close(host->rmt_fd);
	host->rmt_fd = newfd;


    } else {
	//client
	vtun_syslog(LOG_ERR, "进入client");
	//debug
	i = getaddrinfo(vtun.svr_name, "9000", &hints, &srvinfo);
	vtun_syslog(LOG_ERR, "建立sctp socket");
	if (i != 0) {
	    fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(i));
	    return -1;
	}
	for (p = srvinfo; p != NULL; p = p->ai_next) {
	    s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
	    if (s == -1) {
	 vtun_syslog(LOG_ERR, "建立socket失败");
		continue;
	    }

		sleep(2);
	    if (connect(s, p->ai_addr, p->ai_addrlen) == -1) {
	 vtun_syslog(LOG_ERR, "不能连接server..");
		continue;
	    }
	    break;
	}
	if (p == NULL) {
	 vtun_syslog(LOG_ERR, "sctp 失败..");
		return -1;
	}

	 vtun_syslog(LOG_ERR, "成功链接.");
	close(host->rmt_fd);
	host->rmt_fd = s;


    }
	return 0;
}
Example #27
0
int no_lzo(struct vtun_host *host)
{
     vtun_syslog(LOG_INFO, "LZO compression is not supported");
     return -1;
}
Example #28
0
static void sig_term(int sig)
{
     vtun_syslog(LOG_INFO,"Terminated");
     client_term = VTUN_SIG_TERM;
}
Example #29
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;
}
Example #30
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;
}