コード例 #1
0
ファイル: tcp.c プロジェクト: a12e/requindesfils
void handle_tcp(const unsigned char *bytes, uint16_t segment_len) {
    struct tcphdr *tcp_hdr = (struct tcphdr *) bytes;
    tcp_hdr->th_sport = ntohs(tcp_hdr->th_sport);
    tcp_hdr->th_dport = ntohs(tcp_hdr->th_dport);
    printf2("TCP     %u -> %u, [", tcp_hdr->th_sport, tcp_hdr->th_dport);
    print_flags(tcp_hdr->th_flags);
    print2("], ");
    printf2("seq %u, ack %u, win %u\n", ntohl(tcp_hdr->seq), ntohl(tcp_hdr->ack_seq), ntohs(tcp_hdr->window));

    int data_offset = 4 * tcp_hdr->th_off;
    const unsigned char *end = bytes + data_offset;
    bytes += sizeof(struct tcphdr);

    while(bytes < end) {
        uint8_t kind = *bytes++;

        uint8_t len = 0;
        if(kind != 0 && kind != 1)
            len = *bytes++;

        printf3("        option %u: ", kind);
        switch(kind) {
            case 0: print3("end of options"); break;
            case 1: print3("no operation (NOP)"); break;
            case 2: printf3("MSS %u", (*(uint32_t*) bytes)); break;
            case 3: print3("window scale"); break;
            case 4: print3("SACK permited"); break;
            case 5: print3("SACK"); break;
            case 8: print3("timestamps"); break;
            default: print3("unknown"); break;
        }
        print3("\n");

        // advance by the size of the option read
        if(kind != 0 && kind != 1)
            bytes += len - 2;
    }

    if(tcp_hdr->th_sport == 80 || tcp_hdr->th_dport == 80) {
        handle_http((const char *) bytes);
    }
    else if(tcp_hdr->th_sport == 23 || tcp_hdr->th_dport == 23) {
        handle_telnet(bytes, segment_len - data_offset);
    }
    else {
        printf1("???     Unknown TCP application with ports %u -> %u\n", tcp_hdr->th_sport, tcp_hdr->th_dport);
    }
}
コード例 #2
0
ファイル: dserve_net.c プロジェクト: JackieXie168/whitedb
int run_server(int port, dserve_global_p globalptr) {
  struct sockaddr_in clientaddr;
  int rc, sd, connsd, next; 
  thread_data_p tdata; 
  struct common_data *common;
  long tid, maxtid, tcount, i;
  size_t clientlen;
  //struct timeval timeout;
#ifdef MULTI_THREAD
#if _MSC_VER
  HANDLE thandle;
  HANDLE thandlearray[MAX_THREADS];
  DWORD threads[MAX_THREADS];
#else
  pthread_t threads[MAX_THREADS];
  pthread_attr_t attr;
  struct timespec tim, tim2;
#endif
#ifdef USE_OPENSSL    
  SSL_CTX *ctx; 
  SSL *ssl;  
#endif 
#endif
#if _MSC_VER
  void* db=NULL; // actual database pointer
  WSADATA wsaData;
   
  if (WSAStartup(MAKEWORD(2, 0),&wsaData) != 0) {
    errprint(WSASTART_ERR,NULL);
    exit(ERR_EX_UNAVAILABLE);
  }
  db = wg_attach_existing_database("1000");
  //db = wg_attach_database(database,100000000);
  if (!db) {
    errprint(DB_ATTACH_ERR,NULL);
    exit(ERR_EX_UNAVAILABLE);
  }
#else 
  signal(SIGPIPE,SIG_IGN); // important for linux TCP/IP handling   
#endif  
  tdata=&(globalptr->threads_data[0]); 
#ifdef MULTI_THREAD    
#if _MSC_VER
#else
  if (THREADPOOL) {
  
    // ---------------- run as server with threadpool -----------
    
    infoprint(THREADPOOL_INFO,NULL);
    // setup nanosleep for 100 microsec
    tim.tv_sec = 0;
    tim.tv_nsec = 100000;   
#ifdef USE_OPENSSL    
    // prepare openssl    
    ctx=init_openssl(globalptr->conf);
#endif    
    // prepare threads
    common=(struct common_data *)malloc(sizeof(struct common_data));
    tid=0;
    tcount=0;
    maxtid=0;
    if (pthread_mutex_init(&(common->mutex),NULL) !=0 ||
        pthread_cond_init(&(common->cond),NULL) != 0 ||
        pthread_attr_init(&attr) !=0) {
      errprint(MUTEX_ERROR,NULL);    
      exit(ERR_EX_UNAVAILABLE);
    }        
    common->threads = threads;
    common->queue = (common_task_t *)malloc(sizeof(common_task_t) * QUEUE_SIZE);
    common->thread_count = 0;
    common->queue_size = QUEUE_SIZE;
    common->head = common->tail = common->count = 0;
    common->shutdown = common->started = 0;
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); //PTHREAD_CREATE_DETACHED);
    // create threads
    for(tid=0;tid<MAX_THREADS;tid++) {
      // init thread data block 
      tdata[tid].isserver=1;
      tdata[tid].thread_id=tid;
      tdata[tid].realthread=2;
      tdata[tid].common=common;
      tdata[tid].inuse=0;
      tdata[tid].conn=0;
      tdata[tid].ip=NULL;
      tdata[tid].port=0;
      tdata[tid].method=0;
      tdata[tid].res=0; 
      tdata[tid].global=globalptr;
      //fprintf(stderr,"creating thread %d tcount %d \n",(int)tid,(int)tcount); 
      rc=pthread_create(&threads[tid], &attr, handle_http, (void *) &tdata[tid]);
      if (rc) {
        errprint(THREAD_CREATE_ERR,strerror(errno));
        exit(ERR_EX_UNAVAILABLE);
      }      
      tcount++;
    }
    //
    sd=open_listener(port);
    if (sd<0) {
      errprint(PORT_LISTEN_ERR, strerror(errno));
      return -1;
    }
    clientlen = sizeof(clientaddr);
    // loop forever, servicing requests
    while (1) {
      connsd=accept(sd,(struct sockaddr *)&clientaddr, &clientlen);
      if (connsd<0) {
        warnprint(CONN_ACCEPT_WARN, strerror(errno));
        continue;
      }  
      if(pthread_mutex_lock(&(common->mutex)) != 0) {
        errprint(THREADPOOL_LOCK_ERR,NULL);
        exit(ERR_EX_UNAVAILABLE);
      }  
#ifdef USE_OPENSSL
      ssl = SSL_new(ctx);  // get new SSL state with context
      SSL_set_fd(ssl,connsd);	
#endif
      // now we have a connection: add to queue
      next=common->tail+1;
      next=(next==common->queue_size) ? 0 : next;
      do {
        if(common->count==common->queue_size) { // full?
          //fprintf(stderr, "queue full\n");
          nanosleep(&tim , &tim2);
          break; //continue;
        }
        if(common->shutdown) { 
          warnprint(SHUTDOWN_WARN,NULL);
          break;
        }
        // add to task queue
        common->queue[common->tail].conn=connsd;
#ifdef USE_OPENSSL
        common->queue[common->tail].ssl=ssl; 
#endif
        common->tail=next;
        common->count+=1;
        //printf("next %d\n",next);
        // broadcast
        if(pthread_cond_signal(&(common->cond)) != 0) {
          warnprint(COND_SIGNAL_FAIL_WARN,NULL);
          break;
        }
      } while(0);
      //fprintf(stderr,"starting to unlock \n");
      if(pthread_mutex_unlock(&(common->mutex)) != 0) {
        errprint(THREADPOOL_UNLOCK_ERR,NULL);
        exit(ERR_EX_UNAVAILABLE);
      }
    }
    return 0; // never come to this
    
  } else 
#endif // threadpool not implemented on windows version: using a non-threadpool version
         {
         
    // ------------- run as server without threadpool -------------
    
    infoprint(MULTITHREAD_INFO,NULL);
    // setup nanosleep for 100 microsec
#if _MSC_VER
#else    
    tim.tv_sec = 0;
    tim.tv_nsec = 100000;
#endif    
    // prepare common block
    common=(struct common_data *)malloc(sizeof(struct common_data));     
    common->shutdown=0;           
    // mark thread data blocks free
    for(i=0;i<MAX_THREADS;i++) {
      tdata[i].inuse=0;      
      tdata[i].common=common;
      tdata[i].global=globalptr;
    }
    // prepare threads
    tid=0;
    tcount=0;
    maxtid=0;    
#if _MSC_VER
#else
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); //PTHREAD_CREATE_JOINABLE); 
#endif
    sd=open_listener(port);
    if (sd<0) {
      errprint(PORT_LISTEN_ERR, strerror(errno));
      return -1;
    }
    clientlen = sizeof(clientaddr);
    while (1) {
      connsd=accept(sd,(struct sockaddr *)&clientaddr, &clientlen);
      if (common->shutdown==1) break; 
      if (connsd<0) {     
        warnprint(CONN_ACCEPT_WARN, strerror(errno));
        continue;
      }
      tid=-1;
      // find first free thread data block
      // loop until we get a free one
      while(tid<0) {
        for(i=0;i<MAX_THREADS;i++) {
          if (!tdata[i].inuse) {
            tid=i;
            break;
          }
        }
        if (tid>=0) break;
#if _MSC_VER
        usleep(1);
#else
        nanosleep(&tim , &tim2);
#endif
      }
      if (tid>maxtid) maxtid=tid;
      tcount++;
      // init thread data block
      tdata[tid].isserver=1;
      tdata[tid].thread_id=tid;
      tdata[tid].realthread=1;
      tdata[tid].inuse=1;
      tdata[tid].conn=connsd;
      tdata[tid].ip=NULL;
      tdata[tid].port=0;
      tdata[tid].method=0;
      tdata[tid].res=0;  
      tdata[tid].global=globalptr; 
#if _MSC_VER
      tdata[tid].db=db;
      thandle=CreateThread(NULL, 0, handle_http, (void *) &tdata[tid], 0, &threads[tid]);
      if (thandle==NULL) {
        win_err_handler(TEXT("CreateThread"));
        ExitProcess(3);
      } else {
        thandlearray[tid]=thandle;
      }       
#else
      rc=pthread_create(&threads[tid], &attr, handle_http, (void *) &tdata[tid]);
#endif
    }
    return 0; // never come to this
  } 
#else  

  // ------------ run as an iterative server -------------
  
  sd=open_listener(port);
  if (sd<0) {
    errprint(PORT_LISTEN_ERR, strerror(errno));
    return -1;
  }
  clientlen = sizeof(clientaddr);
  while (1) {      
    connsd=accept(sd,(struct sockaddr *)&clientaddr, &clientlen);
    if (connsd<0) {
      warnprint(CONN_ACCEPT_WARN, strerror(errno));
      continue;
    }           
    tid=0;  
    tdata[tid].isserver=1;
    tdata[tid].thread_id=tid;
    tdata[tid].realthread=0;
    tdata[tid].conn=connsd;
    tdata[tid].ip=NULL;
    tdata[tid].port=0;
    tdata[tid].method=0;
    tdata[tid].res=0;  
    tdata[tid].global=globalptr;  
#if _MSC_VER
    tdata[tid].db=db;
#endif
    handle_http((void *) &tdata[tid]);
  }
  return 0; // never come to this
#endif
}