Beispiel #1
0
int
main (int argc, char *argv[])
{
    int sfd;
    struct ev_loop *loop = EV_DEFAULT;

    if (argc < 2) {
        fprintf(stderr, "usage: %s port\n", progname(argv[0]));
        exit(EXIT_FAILURE);
    }

    sfd = bind_and_listen(argv[1]);

    //printf("main: sfd = %d\n", sfd);

    /* Set sfd to non-blocking mode before using with libev */
    set_nonblock(sfd);

    ev_io_init (&listen_watcher, listen_cb, sfd, EV_READ);
    ev_io_start (EV_A_ &listen_watcher);

    /* Start the event loop */
    ev_run (EV_A_ 0);

    return EXIT_SUCCESS;
}
Beispiel #2
0
 void bind_and_listen(const std::string& port,bool reuse_addr,boost::system::error_code& e) {
     try {
         bind_and_listen(port,reuse_addr);
     } catch (const boost::system::system_error& ex) {
         e = ex.code();
         ORCHID_DEBUG("bind_and_listen error: %s",e.message().c_str());
     }
     
 }
Beispiel #3
0
bool 
GSISocketServer::Open()
{
  char portstring[36];

  snprintf(portstring, 35, "%ld", (long int)port);
  sck = bind_and_listen(portstring, backlog, logh);

  return sck != -1;
}
Beispiel #4
0
int
listen_sockaddr(const char *netaddr, void (*cb)(int, void *))
{
	struct addrinfo *result, *res;
	int got_address;

	if ((result = prepare_getaddrinfo(netaddr, 0)) == NULL)
		return -1;

	got_address = 0;
	for (res = result; res != NULL; res = res->ai_next)
		got_address |= bind_and_listen(res, cb);

	freeaddrinfo(result);
	return got_address ? 0 : -1;
}
Beispiel #5
0
int Serv::initServ(struct conf_data *pconf_data)
{
	pepd_conf = new struct epd_config;
	if(pepd_conf == NULL){
		WARNING_LOG("Out of memory.");
		return -1;
	}
	if( init_epd_config(pepd_conf, pconf_data) < 0 ){
		WARNING_LOG("init_epd_config failed");
		return -1;
	}	
	if( bind_and_listen(pepd_conf->server_port) < 0){
		WARNING_LOG("failed to bind and listen!");
		return -1;
	}
	return 0;
}
Beispiel #6
0
/// This is main...
int main(int argc,char* argv[]) {
  int ret;
  in_port_t fixedport = 0;
  struct sockaddr_storage fixedhost;
  struct addrinfo hints, *res, *reslist;
  struct tracker_s * conn;

  memset(&fixedhost, '\0', sizeof(fixedhost));
  printf("netsed " VERSION " by Alexey Shumkin <*****@*****.**>\n"
         "      based on 1.2 from Julien VdG <*****@*****.**>\n"
         "      which is based on 0.01c from Michal Zalewski <*****@*****.**>\n");
  setbuffer(stdout,NULL,0);

  parse_params(argc, argv);

  memset(&hints, '\0', sizeof(hints));
  hints.ai_family = family;
  hints.ai_flags = AI_CANONNAME;
  hints.ai_socktype = tcp ? SOCK_STREAM : SOCK_DGRAM;

  if ((ret = getaddrinfo(rhost, rport, &hints, &reslist))) {
    ERR("getaddrinfo(): %s\n", gai_strerror(ret));
    error("Impossible to resolve remote address or port.");
  }
  /* We have candidates for remote host. */
  for (res = reslist; res; res = res->ai_next) {
    int sd = -1;

    if ( (sd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) < 0)
      continue;
    /* Has successfully built a socket for this address family. */
    /* Record the address structure and the port. */
    fixedport = get_port(res->ai_addr);
    if (!is_addr_any(res->ai_addr))
      memcpy(&fixedhost, res->ai_addr, res->ai_addrlen);
    close(sd);
    break;
  }
  freeaddrinfo(reslist);
  if (res == NULL)
    error("Failed in resolving remote host.");

  if (fixedhost.ss_family && fixedport)
    printf("[+] Using fixed forwarding to %s,%s.\n",rhost,rport);
  else if (fixedport)
    printf("[+] Using dynamic (transparent proxy) forwarding with fixed port %s.\n",rport);
  else if (fixedhost.ss_family)
    printf("[+] Using dynamic (transparent proxy) forwarding with fixed addr %s.\n",rhost);
  else
    printf("[+] Using dynamic (transparent proxy) forwarding.\n");
  if (foreground) {
      printf("Run in foreground...\n");
  } else {
    int x = fork();
    if (x == -1) {
      printf("Error creating a fork. Run in foreground...\n");
    } else if (x) {
      printf("Detached: PID=%d\n", x);
      exit(0);
    }
  }

  bind_and_listen(fixedhost.ss_family, tcp, lport);

  printf("[+] Listening on port %s/%s.\n", lport, (tcp)?"tcp":"udp");

  signal(SIGPIPE, SIG_IGN);
  struct sigaction sa;
  sa.sa_flags = 0;
  sigemptyset(&sa.sa_mask);
  sa.sa_handler = sig_int;
  if (sigaction(SIGINT, &sa, NULL) == -1) error("netsed: sigaction() failed");

  while (!stop) {
    struct sockaddr_storage s;
    socklen_t l = sizeof(s);
    struct sockaddr_storage conho;
    in_port_t conpo;
    char ipstr[INET6_ADDRSTRLEN], portstr[12];

    int sel;
    fd_set rd_set;
    struct timeval timeout, *ptimeout;
    int nfds = lsock;
    FD_ZERO(&rd_set);
    FD_SET(lsock,&rd_set);
    timeout.tv_sec = UDP_TIMEOUT+1;
    timeout.tv_usec = 0;
    ptimeout = NULL;

    {
      conn = connections;
      while(conn != NULL) {
        if(tcp) {
          FD_SET(conn->csock, &rd_set);
          if (nfds < conn->csock) nfds = conn->csock;
        } else {
          // adjust timeout to earliest connection end time
          int remain = UDP_TIMEOUT - (now - conn->time);
          if (remain < 0) remain = 0;
          if (timeout.tv_sec > remain) {
            timeout.tv_sec = remain;
            // time updated to need to timeout
            ptimeout = &timeout;
          }
        }
        FD_SET(conn->fsock, &rd_set);
        if (nfds < conn->fsock) nfds = conn->fsock;
        // point on next
        conn = conn->n;
      }
    }

    sel=select(nfds+1, &rd_set, (fd_set*)0, (fd_set*)0, ptimeout);
    time(&now);
    if (stop)
    {
      break;
    }
    if (sel < 0) {
      DBG("[!] select fail! %s\n", strerror(errno));
      break;
    }
    if (sel == 0) {
      DBG("[*] select timeout. now: %d\n", now);
      // Here we still have to go through the list to expire some udp
      // connection if they timed out... But no descriptor will be set.
      // For tcp, select will not timeout.
    }

    if (FD_ISSET(lsock, &rd_set)) {
      int csock=-1;
      ssize_t rd=-1;
      if (tcp) {
        csock = accept(lsock,(struct sockaddr*)&s,&l);
      } else {
        // udp does not handle accept, so track connections manually
        // also set csock if a new connection need to be registered
        // to share the code with tcp ;)
        rd = recvfrom(lsock,buf,sizeof(buf),0,(struct sockaddr*)&s,&l);
        if(rd >= 0) {
          conn = connections;
          while(conn != NULL) {
            // look for existing connections
            if ((conn->csl == l) && (0 == memcmp(&s, conn->csa, l))) {
              // found
              break;
            }
            // point on next
            conn = conn->n;
          }
          // not found
          if(conn == NULL) {
            // udp 'connection' socket is the listening one
            csock = lsock;
          } else {
            DBG("[+] Got incoming datagram from existing connection.\n");
          }
        } else {
          ERR("recvfrom(): %s", strerror(errno));
        }
      }

      // new connection (tcp accept, or udp conn not found)
      if ((csock)>=0) {
        int one=1;
        getnameinfo((struct sockaddr *) &s, l, ipstr, sizeof(ipstr),
                    portstr, sizeof(portstr), NI_NUMERICHOST | NI_NUMERICSERV);
        printf("[+] Got incoming connection from %s,%s", ipstr, portstr);
        conn = malloc(sizeof(struct tracker_s));
        if(NULL == conn) error("netsed: unable to malloc() connection tracker struct");
        // protocol specific init
        if (tcp) {
          setsockopt(csock,SOL_SOCKET,SO_OOBINLINE,&one,sizeof(int));
          conn->csa = NULL;
          conn->csl = 0;
          conn->state = ESTABLISHED;
        } else {
          conn->csa = malloc(l);
          if(NULL == conn->csa) error("netsed: unable to malloc() connection tracker sockaddr struct");
          memcpy(conn->csa, &s, l);
          conn->csl = l;
          conn->state = UNREPLIED;
        }
        conn->csock = csock;
        conn->time = now;

        conn->live = malloc(rules * sizeof(struct rule_item));
        if(NULL == conn->live) error("netsed: unable to malloc() connection tracker sockaddr struct");
        memcpy(conn->live, rule_live, rules * sizeof(struct rule_item));

        l = sizeof(s);
#ifndef LINUX_NETFILTER
        // was OK for linux 2.2 nat
        getsockname(csock,(struct sockaddr*)&s,&l);
#else
        // for linux 2.4 and later
        getsockopt(csock, SOL_IP, SO_ORIGINAL_DST,(struct sockaddr*)&s,&l);
#endif
        getnameinfo((struct sockaddr *) &s, l, ipstr, sizeof(ipstr),
                    portstr, sizeof(portstr), NI_NUMERICHOST | NI_NUMERICSERV);
        printf(" to %s,%s\n", ipstr, portstr);
        conpo = get_port((struct sockaddr *) &s);

        memcpy(&conho, &s, sizeof(conho));

        if (fixedport) conpo=fixedport;
        if (fixedhost.ss_family)
          memcpy(&conho, &fixedhost, sizeof(conho));

        // forward to addr
        memcpy(&s, &conho, sizeof(s));
        set_port((struct sockaddr *) &s, conpo);
        getnameinfo((struct sockaddr *) &s, l, ipstr, sizeof(ipstr),
                    portstr, sizeof(portstr), NI_NUMERICHOST | NI_NUMERICSERV);
        printf("[*] Forwarding connection to %s,%s\n", ipstr, portstr);

        // connect will bind with some dynamic addr/port
        conn->fsock = socket(s.ss_family, tcp ? SOCK_STREAM : SOCK_DGRAM, 0);

        if (connect(conn->fsock,(struct sockaddr*)&s,l)) {
           printf("[!] Cannot connect to remote server, dropping connection.\n");
           freetracker(conn);
           conn = NULL;
        } else {
          setsockopt(conn->fsock,SOL_SOCKET,SO_OOBINLINE,&one,sizeof(int));
          conn->n = connections;
          connections = conn;
        }
      }
      // udp has data process forwarding
      if((rd >= 0) && (conn != NULL)) {
        b2server_sed(conn, rd);
      }
    } // lsock is set
    // all other sockets
    conn = connections;
    struct tracker_s ** pconn = &connections;
    while(conn != NULL) {
      // incoming data ?
      if(tcp && FD_ISSET(conn->csock, &rd_set)) {
        client2server_sed(conn);
      }
      if(FD_ISSET(conn->fsock, &rd_set)) {
        server2client_sed(conn);
      }
      // timeout ? udp only
      DBG("[!] connection last time: %d, now: %d\n", conn->time, now);
      if(!tcp && ((now - conn->time) >= UDP_TIMEOUT)) {
        DBG("[!] connection timeout.\n");
        conn->state = TIMEOUT;
      }
      if(conn->state >= DISCONNECTED) {
        // remove it
        (*pconn)=conn->n;
        freetracker(conn);
        conn=(*pconn);
      } else {
        // point on next
        pconn = &(conn->n);
        conn = conn->n;
      }
    }
  }

  clean_socks();
  exit(0);
}
Beispiel #7
0
int main(int argc, char* argv[])
{
    signal(SIGSEGV, crash_sig);
    signal(SIGABRT, crash_sig);
    signal(SIGPIPE, SIG_IGN);

    char cmd[1024];
    int localfd, remotefd;
    library_conf_t conf;
    int opt;
    char* ip = NULL;
    unsigned int port = 6687;
    struct in_addr a;

    struct option long_options[] = {
        {"aes",          1, NULL, 'a'},
        {"des",          1, NULL, 'd'},
        {"gzip",         0, NULL, 'g'},
        {"mask",         1, NULL, 'm'},
        {"localip",      1, NULL, 'l'},
        {"server",       1, NULL, 's'},
        {"port",         1, NULL, 'p'},
        {NULL,           0, NULL,   0}
    };
    char short_options[512] = {0};
    longopt2shortopt(long_options, sizeof(long_options) / sizeof(struct option), short_options);

    conf.localip      = 0;
    conf.netmask      = 24;
    conf.use_gzip     = 0;
    conf.use_aes      = 0;
    conf.aes_key_file = NULL;
    conf.use_des      = 0;
    conf.des_key_file = NULL;

    while ((opt = getopt_long(argc, argv, short_options, long_options, NULL)) != -1)
    {
        switch (opt)
        {
        case 'a':
            conf.use_aes = 1;
            conf.aes_key_file = optarg;
            break;
        case 'd':
            conf.use_des = 1;
            conf.des_key_file = optarg;
            break;
        case 'g':
            conf.use_gzip = 1;
            break;
        case 'l':
            conf.localip = inet_addr(optarg);
            break;
        case 's':
            ip = optarg;
            break;
        case 'm':
            conf.netmask = atoi(optarg);
            break;
        case 'p':
            port = atoi(optarg);
            break;
        default:
            fprintf(stderr, "param error\n");
            return 1;
        }
    }

    if (conf.localip == 0)
    {
        fprintf(stderr, "localip is zero\n");
        return 1;
    }
    if (port == 0)
    {
        fprintf(stderr, "port is zero\n");
        return 1;
    }

    memset(this.dev_name, 0, IFNAMSIZ);
    localfd = tun_open(this.dev_name);
    if (localfd == -1) return 1;
    fprintf(stdout, "%s opened\n", this.dev_name);
    a.s_addr = conf.localip;

    if (ip == NULL)
    {
        if (conf.netmask == 0 || conf.netmask > 31)
        {
            fprintf(stderr, "netmask must > 0 and <= 31\n");
            return 1;
        }
        library_init(conf);
        remotefd = bind_and_listen(port);
        if (remotefd == -1) return 1;
        sprintf(cmd, "ifconfig %s %s/%u up", this.dev_name, inet_ntoa(a), conf.netmask);
        SYSTEM_EXIT(cmd);
        a.s_addr = conf.localip & LEN2MASK(conf.netmask);
        sprintf(cmd, "route add -net %s/%u dev %s", inet_ntoa(a), conf.netmask, this.dev_name);
        SYSTEM_EXIT(cmd);
        server_loop(remotefd, localfd);
    }
    else
    {
        unsigned char mask;
        int inited = 0;
        library_init(conf);

        while (1)
        {
            remotefd = connect_server(ip, port);
            if (remotefd == -1)
            {
                sleep(5);
                continue;
            }
            if (!inited)
            {
                sprintf(cmd, "ifconfig %s %s up", this.dev_name, inet_ntoa(a));
                SYSTEM_EXIT(cmd);
                mask = netmask();
                a.s_addr = conf.localip & LEN2MASK(mask);
                sprintf(cmd, "route add -net %s/%u dev %s", inet_ntoa(a), mask, this.dev_name);
                SYSTEM_EXIT(cmd);
                inited = 1;
            }
            client_loop(remotefd, localfd);
            close(remotefd);
            fprintf(stderr, "retry\n");
        }
    }
    return 0;
}
Beispiel #8
0
int
lrmd_init_remote_tls_server()
{
    int rc;
    int filter;
    int port = crm_default_remote_port();
    struct addrinfo hints, *res = NULL, *iter;
    char port_str[6]; // at most "65535"
    gnutls_datum_t psk_key = { NULL, 0 };

    static struct mainloop_fd_callbacks remote_listen_fd_callbacks = {
        .dispatch = lrmd_remote_listen,
        .destroy = lrmd_remote_connection_destroy,
    };

    crm_notice("Starting TLS listener on port %d", port);
    crm_gnutls_global_init();
    gnutls_global_set_log_function(debug_log);

    if (pcmk__init_tls_dh(&dh_params) != GNUTLS_E_SUCCESS) {
        return -1;
    }
    gnutls_psk_allocate_server_credentials(&psk_cred_s);
    gnutls_psk_set_server_credentials_function(psk_cred_s, lrmd_tls_server_key_cb);
    gnutls_psk_set_server_dh_params(psk_cred_s, dh_params);

    /* The key callback won't get called until the first client connection
     * attempt. Do it once here, so we can warn the user at start-up if we can't
     * read the key. We don't error out, though, because it's fine if the key is
     * going to be added later.
     */
    rc = lrmd_tls_set_key(&psk_key);
    if (rc != 0) {
        crm_warn("A cluster connection will not be possible until the key is available");
    }
    gnutls_free(psk_key.data);

    memset(&hints, 0, sizeof(struct addrinfo));
    /* Bind to the wildcard address (INADDR_ANY or IN6ADDR_ANY_INIT).
     * @TODO allow user to specify a specific address
     */
    hints.ai_flags = AI_PASSIVE;
    hints.ai_family = AF_UNSPEC; /* Return IPv6 or IPv4 */
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    snprintf(port_str, sizeof(port_str), "%d", port);
    rc = getaddrinfo(NULL, port_str, &hints, &res);
    if (rc) {
        crm_err("Unable to get IP address info for local node: %s",
                gai_strerror(rc));
        return -1;
    }

    iter = res;
    filter = AF_INET6;
    /* Try IPv6 addresses first, then IPv4 */
    while (iter) {
        if (iter->ai_family == filter) {
            ssock = bind_and_listen(iter);
        }
        if (ssock != -1) {
            break;
        }

        iter = iter->ai_next;
        if (iter == NULL && filter == AF_INET6) {
            iter = res;
            filter = AF_INET;
        }
    }

    if (ssock < 0) {
        goto init_remote_cleanup;
    }

    mainloop_add_fd("pacemaker-remote-server", G_PRIORITY_DEFAULT, ssock, NULL,
                    &remote_listen_fd_callbacks);

    rc = ssock;

  init_remote_cleanup:
    if (rc < 0) {
        close(ssock);
        ssock = 0;
    } else {
        crm_debug("Started TLS listener on port %d", port);
    }
    freeaddrinfo(res);
    return rc;
}
Beispiel #9
0
int
lrmd_init_remote_tls_server(int port)
{
    int rc;
    int filter;
    struct addrinfo hints, *res = NULL, *iter;
    char port_str[16];

    static struct mainloop_fd_callbacks remote_listen_fd_callbacks = {
        .dispatch = lrmd_remote_listen,
        .destroy = lrmd_remote_connection_destroy,
    };

    crm_notice("Starting a tls listener on port %d.", port);
    crm_gnutls_global_init();
    gnutls_global_set_log_function(debug_log);

    gnutls_dh_params_init(&dh_params);
    gnutls_dh_params_generate2(dh_params, 1024);
    gnutls_psk_allocate_server_credentials(&psk_cred_s);
    gnutls_psk_set_server_credentials_function(psk_cred_s, lrmd_tls_server_key_cb);
    gnutls_psk_set_server_dh_params(psk_cred_s, dh_params);

    memset(&hints, 0, sizeof(struct addrinfo));
    hints.ai_flags = AI_PASSIVE; /* Only return socket addresses with wildcard INADDR_ANY or IN6ADDR_ANY_INIT */
    hints.ai_family = AF_UNSPEC; /* Return IPv6 or IPv4 */
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    snprintf(port_str, sizeof(port_str), "%d", port);
    rc = getaddrinfo(NULL, port_str, &hints, &res);
    if (rc) {
        crm_err("getaddrinfo: %s", gai_strerror(rc));
        return -1;
    }

    iter = res;
    filter = AF_INET6;
    /* Try IPv6 addresses first, then IPv4 */
    while (iter) {
        if (iter->ai_family == filter) {
            ssock = bind_and_listen(iter);
        }
        if (ssock != -1) {
            break;
        }

        iter = iter->ai_next;
        if (iter == NULL && filter == AF_INET6) {
            iter = res;
            filter = AF_INET;
        }
    }

    if (ssock < 0) {
        crm_err("unable to bind to address");
        goto init_remote_cleanup;
    }

    mainloop_add_fd("lrmd-remote", G_PRIORITY_DEFAULT, ssock, NULL, &remote_listen_fd_callbacks);

    rc = ssock;
  init_remote_cleanup:
    if (rc < 0) {
        close(ssock);
        ssock = 0;
    }
    freeaddrinfo(res);
    return rc;

}
Beispiel #10
0
int main( int argc, char *argv[] )
{
        struct sockaddr_storage myaddr,remote;
        struct server_ctx ctx;
        int cli_fd, ret;
        socklen_t addrlen;
        char peer[INET6_ADDRSTRLEN];
        void *ptr;

        if ( signal( SIGTERM, sighandler ) == SIG_ERR ) {
                fprintf(stderr, "Unable to set signal handler\n");
                return EXIT_FAILURE;
        }
        if ( signal( SIGINT, sighandler ) == SIG_ERR ) {
                fprintf(stderr, "Unable to set signal handler\n");
                return EXIT_FAILURE;
        }
        if ( signal( SIGPIPE, sighandler ) == SIG_ERR ) {
                fprintf(stderr, "Unable to set signal handler\n");
                return EXIT_FAILURE;
        }

        memset( &ctx, 0, sizeof( ctx ));
        ctx.port = DEFAULT_PORT;
        ctx.recvbuf_size = RECVBUF_SIZE;

        partial_store_init(&ctx.partial);

        ret = parse_args( argc, argv, &ctx );
        if ( ret  < 0 ) {
                WARN("Error while parsing command line\n" );
                return EXIT_FAILURE;
        } else if ( ret == 0 ) {
                return EXIT_SUCCESS;
        }
        

        memset( &myaddr, 0, sizeof( myaddr));
        myaddr.ss_family = AF_INET6;

        if ( is_flag( ctx.options, SEQ_FLAG )) {
                DBG("Using SEQPKT socket\n");
                ctx.sock = socket( PF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP );
        } else {
                DBG("Using STREAM socket\n");
                ctx.sock = socket( PF_INET6, SOCK_STREAM, IPPROTO_SCTP );
        }
        if ( ctx.sock < 0 ) {
                fprintf(stderr, "Unable to create socket: %s \n", strerror(errno));
                return EXIT_FAILURE;
        }
        if (ctx.initmsg != NULL ) {
                TRACE("Requesting for %d output streams and at max %d input streams\n",
                                ctx.initmsg->sinit_num_ostreams,
                                ctx.initmsg->sinit_max_instreams);
                if (setsockopt( ctx.sock, SOL_SCTP, SCTP_INITMSG, 
                                        ctx.initmsg, sizeof(*ctx.initmsg)) < 0) {
                        fprintf(stderr,"Warning: unable to set the association parameters: %s\n",
                                        strerror(errno));
                }
        }

        if ( bind_and_listen( &ctx ) < 0 ) {
                fprintf(stderr, "Error while initializing the server\n" );
                close(ctx.sock);
                return EXIT_FAILURE;
        }

        if ( is_flag( ctx.options, VERBOSE_FLAG ))  
                subscribe_to_events(ctx.sock); /* to err is not fatal */

        memset( &remote, 0, sizeof(remote));
        addrlen = sizeof( struct sockaddr_in6);

        TRACE("Allocating %d bytes for recv buffer \n", ctx.recvbuf_size );
        ctx.recvbuf = mem_alloc( ctx.recvbuf_size * sizeof( uint8_t ));

        printf("Listening on port %d \n", ctx.port );
        while ( !close_req ) {
                if ( is_flag( ctx.options, SEQ_FLAG ) ) {
                        ret = do_server( &ctx, ctx.sock );
                        if ( ret == SERVER_ERROR )
                                break;
                } else {
                        cli_fd = do_accept( &ctx, &remote, &addrlen );
                        if ( cli_fd < 0 ) {
                                if ( errno == EINTR ) 
                                        break;

                                close( ctx.sock );
                                mem_free( ctx.recvbuf);
                                WARN( "Error in accept!\n");
                                return EXIT_FAILURE;
                        } else if ( cli_fd == 0 ) {
                                break;
                        }
                        if ( remote.ss_family == AF_INET ) {
                                ptr = &(((struct sockaddr_in *)&remote)->sin_addr);
                        } else {
                                ptr = &(((struct sockaddr_in6 *)&remote)->sin6_addr);
                        }
                        if ( inet_ntop(remote.ss_family, ptr, peer,
                                                INET6_ADDRSTRLEN ) != NULL ) {
                                printf("Connection from %s \n", peer );
                        } else {
                                printf("Connection from unknown\n");
                        }
                        if( do_server( &ctx, cli_fd ) == SERVER_ERROR ) {
                                close( cli_fd);
                                break;
                        }
                        close( cli_fd );
                }
        }
        mem_free( ctx.recvbuf);
        if (ctx.initmsg != NULL ) {
                mem_free( ctx.initmsg);
        }
        close( ctx.sock );

        return EXIT_SUCCESS;
}
Beispiel #11
0
int main(int argc, char* argv[])
{
#ifdef HAVE_EXECINFO_H
    signal(SIGSEGV, crash_sig);
    signal(SIGABRT, crash_sig);
    signal(SIGPIPE, SIG_IGN);
#endif

#ifdef WIN32
    HANDLE localfd;
    WSADATA wsa;
    enum_device_t devs[MAX_DEVICE_COUNT];
#else
    int localfd;
#endif
    char cmd[1024];
    int remotefd;
    library_conf_t conf;
    int opt;
    struct in_addr a;

    struct option long_options[] = {
        { "conf", 1, NULL, 'c' },
        { NULL,   0, NULL,  0  }
    };
    char short_options[512] = {0};
    longopt2shortopt(long_options, sizeof(long_options) / sizeof(struct option), short_options);
#ifdef HAVE_SYSLOG_H
    openlog(argv[0], LOG_PERROR | LOG_CONS | LOG_PID, LOG_LOCAL0);
#endif

    qtun = calloc(sizeof(*qtun), 1);

#ifdef WIN32
    remotefd = -1;
    localfd = INVALID_HANDLE_VALUE;
#else
    localfd = remotefd = -1;
#endif
    {
        char path[MAX_PATH] = {0};
#ifdef WIN32
        strcpy(path, argv[0]);
#elif defined(__APPLE__)
        char tmp_path[sizeof(path)] = {0};
        uint32_t len = sizeof(path);
        if (_NSGetExecutablePath(tmp_path, &len) == -1) {
            perror("_NSGetExecutablePath");
            return 1;
        }
        if (readlink(tmp_path, path, sizeof(path)) == -1) {
            if (errno == EINVAL) strcpy(path, tmp_path);
            else {
                perror("readlink");
                return 1;
            }
        }
#else
        if (readlink("/proc/self/exe", path, sizeof(path)) == -1)
        {
            perror("readlink");
            return 1;
        }
#endif
        init_path(path);
    }
    conf_init(&conf);

    while ((opt = getopt_long(argc, argv, short_options, long_options, NULL)) != -1)
    {
        switch (opt)
        {
        case 'c':
            {
                char* path = realpath(optarg, NULL);
                if (path == NULL) {
                    perror("realpath");
                    return 1;
                }
                strcpy(conf.conf_file, path);
                free(path);
            }
            break;
        default:
            fprintf(stderr, "param error\n");
            return 1;
        }
    }

#ifdef WIN32
    {
        size_t count = enum_devices(devs);
        if (count == 0)
        {
            fprintf(stderr, "have no QTun Virtual Adapter\n");
            return 1;
        }
        else if (count == 1)
        {
            strcpy(conf.dev_symbol, devs[0].dev_path);
            strcpy(conf.dev_name, devs[0].dev_name);
        }
        else
        {
            size_t i;
            char str[20] = { 0 };
            int n = -1;
            printf("Have Adapters:\n");
            for (i = 0; i < count; ++i)
            {
                printf("%lu: %s\n", i + 1, devs[i].dev_name);
            }
            printf("Choose One[1]: ");
            while (n == -1)
            {
                if (str[0] == '\n' && str[1] == 0) n = 1;
                else
                {
                    if (!is_int(str, sizeof(str))) continue;
                    n = atoi(str);
                    if (n < 1 || n > (int)count)
                    {
                        fprintf(stderr, "Invalid Number must >= 1 and <= %lu\n", count);
                        n = -1;
                        continue;
                    }
                }
            }
            strcpy(conf.dev_symbol, devs[n].dev_path);
            strcpy(conf.dev_name, devs[n].dev_name);
        }
    }
#endif
    
    init_lua();
    show_logo();
    script_load_config(qtun->lua, &conf, conf.conf_file);

#ifdef WIN32
    if (strlen(conf.dev_symbol) == 0)
    {
        fprintf(stderr, "Missing param [-e] or [--device]\n");
        return 1;
    }
#endif

#ifdef WIN32
    localfd = tun_open(conf.dev_symbol);
    if (localfd == INVALID_HANDLE_VALUE) return 1;
    fprintf(stdout, "%s opened\n", conf.dev_name);
#else
    memset(qtun->dev_name, 0, IFNAMSIZ);
    localfd = tun_open(qtun->dev_name);
    if (localfd == -1) return 1;
    syslog(LOG_INFO, "%s opened\n", qtun->dev_name);
#endif
    a.s_addr = conf.localip;

#ifdef WIN32
    WSAStartup(MAKEWORD(2, 2), &wsa);
#endif
    if (strlen(conf.server) == 0)
    {
        if (conf.netmask == 0 || conf.netmask > 31)
        {
#ifdef WIN32
            WSACleanup();
#endif

            fprintf(stderr, "netmask must > 0 and <= 31\n");
            return 1;
        }
        library_init(conf);
        if (conf.localip == 0)
        {
            fprintf(stderr, "localip is zero\n");
            return 1;
        }
        if (strlen(conf.signature_file) == 0) {
            fprintf(stderr, "missing signature file\n");
            return 1;
        }
        qtun->is_server = 1;
        remotefd = bind_and_listen(conf.server_port);
        if (remotefd == -1)
        {
#ifdef WIN32
            WSACleanup();
#endif
            return 1;
        }
#ifdef WIN32
        {
            a.s_addr = conf.localip;
            sprintf(cmd, "netsh interface ip set address name=\"%s\" static %s %s", conf.dev_name, inet_ntoa(a), STR_LEN2MASK(conf.netmask));
            SYSTEM_EXIT(cmd);
        }
#elif defined(__APPLE__)
        {
            sprintf(cmd, "ifconfig %s %s/%u up", qtun->dev_name, inet_ntoa(a), conf.netmask);
            SYSTEM_EXIT(cmd);
            a.s_addr = conf.localip & LEN2MASK(conf.netmask);
            sprintf(cmd, "route add -net %s/%u %s", inet_ntoa(a), conf.netmask, inet_ntoa(a));
            SYSTEM_EXIT(cmd);
        }
#else
        {
            sprintf(cmd, "ifconfig %s %s/%u up", qtun->dev_name, inet_ntoa(a), conf.netmask);
            SYSTEM_EXIT(cmd);
            a.s_addr = conf.localip & LEN2MASK(conf.netmask);
            sprintf(cmd, "route add -net %s/%u dev %s", inet_ntoa(a), conf.netmask, qtun->dev_name);
            SYSTEM_EXIT(cmd);
        }
#endif
        server_loop(remotefd, localfd);
    }
    else
    {
#ifdef unix
        unsigned char mask;
#endif
        int inited = 0;
        library_init(conf);
        qtun->is_server = 0;
        while (1)
        {
            remotefd = connect_server(conf.server, conf.server_port);
            if (remotefd == -1)
            {
                SLEEP(5);
                continue;
            }
            a.s_addr = qtun->localip;
            if (qtun->localip == 0)
            {
                fprintf(stderr, "localip is zero\n");
                return 1;
            }
            if (strlen(conf.signature_file) == 0) {
                fprintf(stderr, "missing signature file\n");
                return 1;
            }
            if (!inited)
            {
#ifdef WIN32
                {
                    sprintf(cmd, "netsh interface ip set address name=\"%s\" static %s %s", conf.dev_name, inet_ntoa(a), STR_LEN2MASK(conf.netmask));
                    SYSTEM_EXIT(cmd);
                }
#elif defined(__APPLE__)
                {
                    char ip1[16], ip2[16];
                    a.s_addr = qtun->localip;
                    strcpy(ip1, inet_ntoa(a));
                    a.s_addr = qtun->client.local_ip;
                    strcpy(ip2, inet_ntoa(a));
                    sprintf(cmd, "ifconfig %s inet %s %s up", qtun->dev_name, ip1, ip2);
                    SYSTEM_EXIT(cmd);
                    mask = netmask();
                    a.s_addr = qtun->localip & LEN2MASK(mask);
                    sprintf(cmd, "route add -net %s/%u %s", inet_ntoa(a), mask, ip2);
                    SYSTEM_EXIT(cmd);
                }
#else
                {
                    sprintf(cmd, "ifconfig %s %s up", qtun->dev_name, inet_ntoa(a));
                    SYSTEM_EXIT(cmd);
                    mask = netmask();
                    a.s_addr = qtun->localip & LEN2MASK(mask);
                    sprintf(cmd, "route add -net %s/%u dev %s", inet_ntoa(a), mask, qtun->dev_name);
                    SYSTEM_EXIT(cmd);
                }
#endif
                inited = 1;
            }
            client_loop(remotefd, localfd);
            close(remotefd);
            SYSLOG(LOG_WARNING, "retry");
        }
    }
#ifdef WIN32
    WSACleanup();
#endif

#ifdef HAVE_SYSLOG_H
    closelog();
#endif

    library_free();
    return 0;
}