⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 client_handler.c

📁 NAT打洞
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "client_handler.h"

unsigned nclients = 0;

int timer_disabled = 0;
long last_registration = 0;

int server_read(CLIENT_DATA *cd);
int client_write(CLIENT_DATA *cd);
int client_exception(CLIENT_DATA *cd);
int client_read(CLIENT_DATA *cd);
int client_connected(CLIENT_DATA *cd);
int client_request(CLIENT_DATA *cd);
int register_on_server(void);
int proxy_ping_reply(CLIENT_DATA *cd);
int proxy_bind_reply(CLIENT_DATA *cd);
int proxy_close_reply(CLIENT_DATA *cd);
int proxy_bound_ok_replay(CLIENT_DATA *cd, int nsize, struct sockaddr_in sa);
int receive_packet(CLIENT_DATA *cd, int nsize, struct sockaddr_in sa);

int client_handler(void *data, MASTER_FD* master, int what){
        CLIENT_DATA *cd = (CLIENT_DATA *)data;
        if(cd->step == CLIENT_LAST_STEP){
    return disconnect(cd);
  }
  cd->master = master;
  switch(what){
        case WHAT_READ:
        return client_read(cd);
        case WHAT_WRITE:
        return client_write(cd);
        case WHAT_EXCEPTION:
        return client_exception(cd);
  }
  return MASTER_ALL;

}

int master_walker(void* data, void *data1){
        CLIENT_DATA *cd = (CLIENT_DATA *)data;
        CLIENT_DATA *cd1 = (CLIENT_DATA *)data1;
  if(
        (cd->client_type == CLIENT_TYPE_CLIENT) && (cd1->type.udp.control == cd)
        || (cd->client_type == CLIENT_TYPE_UDP) && (cd->type.udp.control == cd1)
  ){
        return 1;
  }
  return 0;
}

int disconnect(CLIENT_DATA *cd){
  if(nclients > 0){
          nclients--;
  }
  last_registration = 0;
  walk_master(sock_data, cd, &master, &master_walker);
  return DISCONNECT;
}

int client_write(CLIENT_DATA *cd){
        int nsize;
        if(cd->type.client.nsize > 0){
    if(send(cd->sock, cd->type.client.buff, cd->type.client.nsize, 0) < 0){
      if(verbose){
        handle_error(__FILE__, __LINE__);
      }
    }
    else {
            if(verbose){
            printf("[%s:%d] <<< %s", inet_ntoa(cd->addr.sin_addr), ntohs(cd->addr.sin_port), cd->type.client.buff);
        }
    }
    cd->type.client.nsize = 0;
        return MASTER_WRITE;
  }
        return 0;
}

#if defined(WIN32) || defined(__WIN32__)
unsigned __stdcall
#else
void*
#endif
server_registration(void* arg){
        int nsize;
  char buff[1024];
        CLIENT_DATA *cd = (CLIENT_DATA *)arg;
  int client_addr_sz = sizeof(struct sockaddr_in);
  if(connect(cd->sock, (struct sockaddr *)&cd->addr, client_addr_sz) != 0){
    if(verbose){
        handle_error(__FILE__, __LINE__);
    }
  }
  else {
          add_socket(cd->sock, sock_data, cd, &master, MASTER_READ);
  }
  return
#if defined(WIN32) || defined(__WIN32__)
                0
#else
                NULL
#endif
        ;
}

CLIENT_DATA *server;

int register_on_server(void){
  SOCKET server_sock;

  server_sock = socket(AF_INET, SOCK_STREAM, 0);
  if(server_sock
#if defined(WIN32) || defined(__WIN32__)
      ==INVALID_SOCKET
#else
      < 0
#endif
  ){
        return 1;
  }
  server = (CLIENT_DATA *)get_client_data(server_sock, server_addr);
  server->client_type = CLIENT_TYPE_SERVER;
  server->step = CLIENT_REQUEST;
#if defined(WIN32) || defined(__WIN32__)
        {
    unsigned thid;
                _beginthreadex(NULL, 0, &server_registration, server, 0, &thid);
  }
#else
        {
        pthread_t thread;
        pthread_create(&thread, NULL, &server_registration, server);
  }
#endif
        return 0;
}


int client_exception(CLIENT_DATA *cd){
        return 0;
}

int client_read(CLIENT_DATA *cd){
  if(cd->step == CLIENT_CONNECTED){
    return client_connected(cd);
  }
  else if(cd->step == CLIENT_REQUEST){
    return client_request(cd);
  }
  else {
  }
  return 0;
}

int server_read(CLIENT_DATA *cd){
  int nsize;
        if(strcmp(buf, sHello) == 0){
                sprintf(buf, "%s: %s; %d; %d\n", registerProxy, listen_address, listen_port, nclients);
    if(send(cd->sock, buf, strlen(buf), 0) < 0){
        if(verbose){
        handle_error(__FILE__, __LINE__);
      }
    }
    else {
            if(verbose){
            printf("[%s:%d] <<< %s", inet_ntoa(cd->addr.sin_addr), ntohs(cd->addr.sin_port), buf);
        }
    }
          return 0;
  }

  else if(is_command(buf, registeredProxy)){
    int i = 0;
    char *p = tokenize_cmd(buf);
    while((p != NULL) && (i < 1)){
      switch(i){
        case 0:
                            registration_period = atoi(p);
          break;
      }
      i++;
      p = tokenize_cmd(NULL);
    }
    timer_disabled = 0;
          return MASTER_ALL;
  }
  return 0;
}

int client_connected(CLIENT_DATA *cd){
  sprintf(buf, "%s", pHello);
  if(send(cd->sock, buf, strlen(buf), 0) < 0){
    if(verbose){
        handle_error(__FILE__, __LINE__);
    }
    return MASTER_ALL;
  }
  if(verbose){
    printf("[%s:%d] <<< %s", inet_ntoa(cd->addr.sin_addr), ntohs(cd->addr.sin_port), buf);
  }
  nclients++;
  last_registration = 0;

  cd->step = CLIENT_REQUEST;
  return 0;
}

int rerecv_cmd(CLIENT_DATA *cd, char *buf, int nsize){
        char *p = strchr(buf, '\r');
  if(p != NULL){
        nsize = p - buf + 1;
  }
        nsize = recv(cd->sock, buf, nsize, 0);
  return nsize;
}

int client_request(CLIENT_DATA *cd){
        int nsize;
  if(cd->client_type != CLIENT_TYPE_UDP){
    if((nsize = recv(cd->sock, buf, BUFFER_SIZE - 1, MSG_PEEK)) < 0){
        if(verbose){
                handle_error(__FILE__, __LINE__);
      }
    }
    if(nsize <= 0){
        recv(cd->sock, buf, BUFFER_SIZE - 1, 0);
      return disconnect(cd);
    }
          nsize = rerecv_cmd(cd, buf, nsize);
    buf[nsize] = 0;
    if(verbose){
//      printf("[%s,%d][%s:%d] >>> %s", __FILE__,__LINE__,inet_ntoa(cd->addr.sin_addr), ntohs(cd->addr.sin_port), buf);
    }
    if(cd->client_type == CLIENT_TYPE_SERVER){
      return server_read(cd);
    }
    else if(cd->client_type == CLIENT_TYPE_CLIENT){
      if(is_command(buf, proxyPing)){
        return proxy_ping_reply(cd);
      }
      else if(is_command(buf, proxyBind)){
        return proxy_bind_reply(cd);
      }
      else if(is_command(buf, proxyClose)){
        return proxy_close_reply(cd);
      }
      else if(is_command(buf, isOverTCP)){
#ifdef OVER_TCP
        return is_over_tcp_reply(cd);
#else
                                return 0;
#endif
      }
      else if(is_command(buf, overTCP)){
#ifdef OVER_TCP
#ifdef AUTH
                    if(!cd->authorized){
printf("[%s,%d] unauthorized\n", __FILE__,__LINE__);
                    return unauthorized(cd);
                }
#endif
        return send_over_tcp(cd, nsize);
#else
                                return 0;
#endif
      }
      else if(is_command(buf, proxyAuth1)){
#ifdef AUTH
                                return auth_1(cd, nsize);
#else
        sprintf(buf, "%s: OK\n", proxyAuth1);
        if(send(cd->sock, buf, strlen(buf), 0)
      #if defined(WIN32) || defined(__WIN32__)
            ==SOCKET_ERROR
      #else
            < 0
      #endif
        ){
          if(verbose){
            handle_error(__FILE__, __LINE__);
          }
        }
    if(verbose){
      printf("[%s,%d][%s:%d] >>> %s", __FILE__,__LINE__,inet_ntoa(cd->addr.sin_addr), ntohs(cd->addr.sin_port), buf);
    }
                                return 0;
#endif
      }
      else if(is_command(buf, proxyAuth2)){
#ifdef AUTH
                                return auth_2(cd, nsize);
#else
                                return 0;
#endif
      }
    }
  }
  else {
        struct sockaddr_in sa;
  #if defined(WIN32) || defined(__WIN32__)
    int
  #else
          unsigned
  #endif
    sz = sizeof(struct sockaddr_in);
    if((nsize = recvfrom(cd->sock, buf, BUFFER_SIZE - 1, 0, (struct sockaddr*)&sa, &sz)) < 0){
            if(verbose){
            handle_error(__FILE__, __LINE__);
      }
    }
    if(nsize <= 0){
            return disconnect(cd);
    }
    buf[nsize] = 0;
    if(verbose){
      printf("[%s:%d] >>> (%s)\n", inet_ntoa(sa.sin_addr), ntohs(sa.sin_port), buf);
    }
    if(
      (sa.sin_addr.s_addr == cd->addr.sin_addr.s_addr)
      && is_command(buf + sizeof(struct sockaddr_in), testOverTCP)
      && (((struct sockaddr_in*)buf)->sin_addr.s_addr == INADDR_NONE)

    ){
#ifdef OVER_TCP
      return test_over_tcp_replay(cd, nsize, sa);
#else
                        return 0;
#endif
    }
    else if(
      (sa.sin_addr.s_addr == cd->addr.sin_addr.s_addr)
      && is_command(buf + sizeof(struct sockaddr_in), proxyBoundOK)
      && (((struct sockaddr_in*)buf)->sin_addr.s_addr == INADDR_NONE)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -