示例#1
0
int TunMainLoop(int tunfd, SOCKET Socket, tBoolean keepalive, int keepalive_interval,
        char *local_address_ipv6, char *keepalive_address)
{
  fd_set rfds;
  int count, maxfd;
  unsigned char bufin[2048];
  unsigned char bufout[2048];
  struct timeval timeout;
  int ret;

  if (keepalive_interval != 0)
  {
    timeout.tv_sec = 0;
    timeout.tv_usec = 100000; // 100 ms
    NetKeepaliveInit(local_address_ipv6, keepalive_address, keepalive_interval, AF_INET6);
  }
  else
  {
    keepalive = FALSE;
    timeout.tv_sec = 7 * 24 * 60 * 60 ; /* one week */
    timeout.tv_usec = 0;
  }

  while( tspCheckForStopOrWait( 0 ) == 0 )
  {
    FD_ZERO(&rfds);
    FD_SET(tunfd,&rfds);
    FD_SET(Socket,&rfds);
    maxfd = tunfd>Socket?tunfd:Socket;

    bufin[0]=0;
    bufin[1]=0;
    bufin[2]=0x86;
    bufin[3]=0xdd;

    if( keepalive )
    {
      // Reinit timeout variable; in linux select modifies it.
      timeout.tv_sec = 0;
      timeout.tv_usec = 100000; // 100 ms
      if (NetKeepaliveDo() == 2)
        return KEEPALIVE_TIMEOUT;
    }

    ret = select(maxfd+1,&rfds,0,0,&timeout);
    if( ret > 0 )
    {
      if( FD_ISSET(tunfd,&rfds) )
      {
        /* data sent through udp tunnel */
        if ( (count = read(tunfd,bufout,sizeof(bufout) )) == -1 )
        {
          Display( LOG_LEVEL_3, ELError, "TunMainLoop",HEX_STR_ERR_READING_TUN_DEV );
          return TUNNEL_ERROR;
        }
        NetKeepaliveGotWrite();
        if (send(Socket,bufout+4,count-4,0) != count-4)
        {
          Display( LOG_LEVEL_3, ELError, "TunMainLoop",HEX_STR_ERR_WRITE_SOCKET );
          return TUNNEL_ERROR;
        }
      }
      if( FD_ISSET(Socket,&rfds) )
      {
        /* data received through udp tunnel */
        count = recvfrom(Socket,bufin+4,2048-4,0,NULL,NULL);
        NetKeepaliveGotRead();
        if( write(tunfd,bufin,count+4) != count+4 )
        {
          Display( LOG_LEVEL_3, ELError, "TunMainLoop", HEX_STR_ERR_WRITE_TUN_DEV );
          return TUNNEL_ERROR;
        }
      }
    }
  }   // while()

  return NO_ERROR;
}
示例#2
0
int TunMainLoop(int tunfd, SOCKET Socket, tBoolean keepalive, int keepalive_interval,
				char *local_address_ipv6, char *keepalive_address_ipv6) {
  fd_set rfds;
  int count, maxfd;
  char bufin[2048];
  char bufout[2048];
  struct timeval timeout;
  int ret = 0;

  if (keepalive_interval != 0) {
	  timeout.tv_sec = 0;
	  timeout.tv_usec = 100000;	// 100 ms
	  NetKeepaliveInit(local_address_ipv6, keepalive_address_ipv6, keepalive_interval);
  }
  else {
	  keepalive = FALSE;
	  timeout.tv_sec = 7 * 24 * 60 * 60 ; /* one week */
	  timeout.tv_usec = 0;
  }

  bufin[0] = 0;
  bufin[1] = 0;
  bufin[2] = 0;
  bufin[3] = 0x1c;

  while(1) {
    FD_ZERO(&rfds); 
    FD_SET(tunfd,&rfds);
	FD_SET(Socket,&rfds);

    maxfd = tunfd>Socket?tunfd:Socket;

	if(keepalive) 
		if (NetKeepaliveDo() == 2)
			return KEEPALIVE_TIMEOUT;
  
    
    ret = select(maxfd+1,&rfds,0,0,&timeout);

    if (ret > 0) {
		if( FD_ISSET(tunfd, &rfds) ) {
			/* data sent through udp tunnel */
			ioctl(tunfd, FIONREAD, &count);
			if (count > sizeof(bufout)) {
				Display(1, ELError, "TunMainLoop", "Error reading from tun device, buffer too small");
				return(TUNNEL_ERROR);
			}
			if (read(tunfd, bufout, count) != count) {
				Display(1, ELError, "TunMainLoop", "Error reading from tun device");
				return(TUNNEL_ERROR);
			}
			NetKeepaliveGotWrite();
			if (send(Socket, bufout+4, count-4, 0) != count-4) {
				Display(1, ELError, "TunMainLoop", "Error writing to socket");
				return(TUNNEL_ERROR);
			}
		}

		if(FD_ISSET(Socket,&rfds)) {
			/* data received through udp tunnel */
			count=recvfrom(Socket,bufin+4,2048 - 4,0,NULL,NULL);
			NetKeepaliveGotRead();
			if (write(tunfd, bufin, count + 4) != count + 4) {
				Display(1, ELError, "TunMainLoop", "Error writing to tun device");
				return(TUNNEL_ERROR);
			}
		}
	}//if (ret>0)
  }//while(1)
}