Changeset 1612

Show
Ignore:
Timestamp:
03/31/08 08:59:17 (5 months ago)
Author:
till
Message:

nebula
- different fd set handling for polling avoids array scanning

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • nebula/trunk/client/nebulaclient.c

    r1588 r1612  
    5757        while (1) { 
    5858                if (read_chars >= len-1) { 
    59                         fprintf(stderr, "Error while reading from socket - Line exceeds buffer.\n"); 
     59                        fprintf(stderr, "Error while reading from socket - Line exceeds buffer (%u bytes).\n", read_chars); 
     60line[read_chars] = 0; 
     61printf("line: %s\n", line); 
    6062                        exit(EXIT_FAILURE); 
    6163                } 
     
    447449                        printf("Warning - Nebula server did not respond within 10 seconds.\n"); 
    448450                } else if (strlen((char *) response) != 2 || strncmp((char *) response, "OK", 2) != 0) 
    449                         printf("Warning - Invalid response from Nebula server.\n"); 
     451                        printf("Warning - Invalid response from Nebula server: %s.\n", response); 
    450452 
    451453                close(sock_fd); 
  • nebula/trunk/src/classify.c

    r1588 r1612  
    239239                        (long unsigned) ((hash*)t->data)->cl->hq->size, ((hash*)t->data)->cl->threshold); 
    240240 
    241                 // set threshold to current size plus 1 
    242                 ((hash*)t->data)->cl->threshold = ((hash*)t->data)->cl->hq->size + 1
     241                // increment size threshold 
     242                ((hash*)t->data)->cl->threshold *= 1.2
    243243 
    244244                if (pthread_attr_init(&ptattr) || 
  • nebula/trunk/src/hash.c

    r1593 r1612  
    4343        free(((hash *)h)->md5sum); 
    4444        ((hash *)h)->md5sum = NULL; 
    45         ((submission *)((hash *)h)->submission)->md5sum = NULL; 
     45 
     46        if (((hash *)h)->submission) 
     47                ((submission *)((hash *)h)->submission)->md5sum = NULL; 
    4648 
    4749        free(((hash *)h)->spamsum); 
  • nebula/trunk/src/nebula.c

    r1611 r1612  
    7979        char            option; 
    8080        pthread_t       ntid; 
    81         submission      s[POLLFD_SET_SIZE], *tmp_submission; 
     81        submission      *tmp_submission; 
    8282        pthread_attr_t  ptattr; 
    8383        struct rlimit   rlim; 
    8484 
    8585 
    86         memset(pfdset, 0, sizeof(struct pollfd) * (POLLFD_SET_SIZE+1)); 
    87         memset(pfdflag, 0, sizeof(u_char) * (POLLFD_SET_SIZE)); 
    88         memset(s, 0, sizeof(submission) * POLLFD_SET_SIZE); 
     86        memset(pfdset, 0, sizeof(struct pollfd) * (POLLFD_MAX_SET_SIZE+1)); 
     87        memset(s, 0, sizeof(submission) * (POLLFD_MAX_SET_SIZE+1)); 
    8988        pollfd_set_size         = 0; 
    9089 
     
    221220                exit(EXIT_FAILURE); 
    222221        } 
    223         if (rlim.rlim_max < POLLFD_SET_SIZE+1) { 
    224                 rlim.rlim_max = rlim.rlim_cur = POLLFD_SET_SIZE+1; 
     222        if (rlim.rlim_max < POLLFD_MAX_SET_SIZE+1) { 
     223                rlim.rlim_max = rlim.rlim_cur = POLLFD_MAX_SET_SIZE+1; 
    225224                if (setrlimit(RLIMIT_NOFILE, &rlim) == -1) { 
    226225                        fprintf(stderr, "Error - Unable to increase maximum number of open files: %s.\n", strerror(errno)); 
     
    295294                                } 
    296295 
    297                                 if ((LISTEN_SOCK.revents & POLLIN) && pollfd_set_size < POLLFD_SET_SIZE) { 
     296                                if ((LISTEN_SOCK.revents & POLLIN) && pollfd_set_size < POLLFD_MAX_SET_SIZE) { 
    298297                                        // incoming connection, accept it and place fd in pollfd set 
    299298                                        pthread_mutex_lock(&sessions_mutex); 
     
    303302                                        pfdset[pollfd_set_size].fd      = net_accept(LISTEN_SOCK.fd); 
    304303                                        pfdset[pollfd_set_size].events  = POLLOUT; 
    305                                         pfdflag[pollfd_set_size]        = 1; 
    306304 
    307305                                        memset(&s[pollfd_set_size], 0, sizeof(submission)); 
     
    309307                                        pthread_mutex_unlock(&sessions_mutex); 
    310308 
    311                                         if (verbose > 1) printf("[>] Connection accepted.\n"); 
     309                                        if (verbose > 1) printf("[>] Connection accepted: %d.\n", pfdset[pollfd_set_size].fd); 
    312310                                } 
    313311                        } 
    314312                        for (i=1; i<=pollfd_set_size; i++) { 
    315                                 if (pfdflag[i] && pfdset[i].revents & POLLOUT) { 
     313                                if (!pfdset[i].revents) continue; 
     314 
     315                                if (pfdset[i].revents & POLLOUT) { 
    316316                                        switch (session_handle_data(&pfdset[i], &s[i])) { 
    317317                                        case -1: 
     
    326326                                                break; 
    327327                                        } 
    328                                 } 
    329                                 if (pfdflag[i] && pfdset[i].revents) { 
    330                                         if (pfdset[i].revents & POLLIN) { 
    331                                                 switch (session_handle_data(&pfdset[i], &s[i])) { 
    332                                                 case 2: 
    333                                                         // need more data to complete session 
    334                                                         break; 
    335                                                 case 1: 
    336                                                         // create clustering thread 
    337                                                         if ((tmp_submission = calloc(1, sizeof(submission))) == NULL) { 
    338                                                                 fprintf(stderr, "Error - Unable to allocate memory: %s.\n", strerror(errno)); 
    339                                                                 exit(EXIT_FAILURE); 
    340                                                         } 
    341                                                         memcpy(tmp_submission, &s[i], sizeof(submission)); 
    342                                                         memset(&s[i], 0, sizeof(submission)); 
    343  
    344                                                         if (pthread_attr_init(&ptattr) || 
    345                                                             pthread_attr_setdetachstate(&ptattr, PTHREAD_CREATE_DETACHED)) { 
    346                                                                 fprintf(stderr, "Error - Unable to initialize thread attributes: %s.\n", strerror(errno)); 
    347                                                                 exit(EXIT_FAILURE); 
    348                                                         } 
    349                                                         pthread_mutex_lock(&sessions_mutex); 
    350                                                         if (pthread_create(&ntid, &ptattr, pt_classify, (void *) tmp_submission)) { 
    351                                                                 fprintf(stderr, "Error - Cannot create clustering thread: %s.\n", strerror(errno)); 
    352                                                                 exit(EXIT_FAILURE); 
    353                                                         } 
    354                                                         pthread_attr_destroy(&ptattr); 
    355  
    356                                                         session_reset(&s[i], i); 
    357                                                         break; 
    358                                                 case 0: 
    359                                                         // connection closed 
    360                                                         session_reset(&s[i], i); 
    361                                                         break; 
    362                                                 case -1: 
    363                                                         // program error 
    364                                                         fprintf(stderr, "Error - Terminating session.\n"); 
    365                                                         session_reset(&s[i], i); 
    366                                                         break; 
    367                                                 case -2: 
    368                                                         // connection state error 
    369                                                         fprintf(stderr, "Error - Invalid connection state.\n"); 
    370                                                         session_reset(&s[i], i); 
    371                                                         break; 
    372                                                 default: 
    373                                                         break; 
     328                                } else if (pfdset[i].revents & POLLIN) { 
     329                                        switch (session_handle_data(&pfdset[i], &s[i])) { 
     330                                        case 2: 
     331                                                // need more data to complete session 
     332                                                break; 
     333                                        case 1: 
     334                                                // create clustering thread 
     335                                                if ((tmp_submission = calloc(1, sizeof(submission))) == NULL) { 
     336                                                        fprintf(stderr, "Error - Unable to allocate memory: %s.\n", strerror(errno)); 
     337                                                        exit(EXIT_FAILURE); 
    374338                                                } 
    375                                         } else if (pfdset[i].revents & POLLERR && errno != EINTR) { 
    376                                                 fprintf(stderr, "Error - Unable to poll socket: %s.\n", strerror(errno)); 
    377                                                 session_reset(&s[i], i); 
    378                                         } else if (pfdset[i].revents & POLLHUP) { 
    379                                                 fprintf(stderr, "Error - Socket hangup.\n"); 
    380                                                 session_reset(&s[i], i); 
    381                                         } else if (pfdset[i].revents & POLLNVAL) { 
    382                                                 fprintf(stderr, "Error - Socket descriptor is invalid.\n"); 
    383                                                 session_reset(&s[i], i); 
     339/* 
     340int j; 
     341for (j=1; j<=pollfd_set_size; j++) printf("-- session %d: fd %d, state %u\n", j, pfdset[j].fd, s[j].state); 
     342*/ 
     343                                                memcpy(tmp_submission, &s[i], sizeof(submission)); 
     344                                                memset(&s[i], 0, sizeof(submission)); 
     345                                                 
     346                                                if (pthread_attr_init(&ptattr) || 
     347                                                    pthread_attr_setdetachstate(&ptattr, PTHREAD_CREATE_DETACHED)) { 
     348                                                        fprintf(stderr, "Error - Unable to initialize thread attributes: %s.\n", strerror(errno)); 
     349                                                        exit(EXIT_FAILURE); 
     350                                                } 
     351                                                pthread_mutex_lock(&sessions_mutex); 
     352                                                if (pthread_create(&ntid, &ptattr, pt_classify, (void *) tmp_submission)) { 
     353                                                        fprintf(stderr, "Error - Cannot create clustering thread: %s.\n", strerror(errno)); 
     354                                                        exit(EXIT_FAILURE); 
     355                                                } 
     356                                                pthread_attr_destroy(&ptattr); 
     357 
     358                                                session_reset(&s[i], i); 
     359/* 
     360for (j=1; j<=pollfd_set_size; j++) printf("== session %d: fd %d, state %u\n", j, pfdset[j].fd, s[j].state); 
     361*/ 
     362                                                break; 
     363                                        case 0: 
     364                                                // connection closed 
     365                                                session_reset(&s[i], i); 
     366                                                break; 
     367                                        case -1: 
     368                                                // program error 
     369                                                fprintf(stderr, "Error - Terminating session.\n"); 
     370                                                session_reset(&s[i], i); 
     371                                                break; 
     372                                        case -2: 
     373                                                // connection state error 
     374                                                fprintf(stderr, "Error - Invalid connection state.\n"); 
     375                                                session_reset(&s[i], i); 
     376                                                break; 
     377                                        default: 
     378                                                break; 
    384379                                        } 
     380                                } else if (pfdset[i].revents & POLLERR && errno != EINTR) { 
     381                                        fprintf(stderr, "Error - Unable to poll socket: %s.\n", strerror(errno)); 
     382                                        session_reset(&s[i], i); 
     383                                } else if (pfdset[i].revents & POLLHUP) { 
     384                                        fprintf(stderr, "Error - Socket hangup.\n"); 
     385                                        session_reset(&s[i], i); 
     386                                } else if (pfdset[i].revents & POLLNVAL) { 
     387                                        fprintf(stderr, "Error - Socket descriptor is invalid.\n"); 
     388                                        session_reset(&s[i], i); 
    385389                                } 
    386390                        } 
  • nebula/trunk/src/nebula.h

    r1611 r1612  
    3636 
    3737 
    38 #define POLLFD_SET_SIZE       255 
    39 #define LISTEN_SOCK     pfdset[0] 
     38#define POLLFD_MAX_SET_SIZE   255 
     39#define LISTEN_SOCK            pfdset[0] 
    4040 
    41 struct pollfd  pfdset[POLLFD_SET_SIZE+1]; 
    42 u_char         pfdflag[POLLFD_SET_SIZE]; 
     41submission     s[POLLFD_MAX_SET_SIZE+1]; 
     42struct pollfd  pfdset[POLLFD_MAX_SET_SIZE+1]; 
    4343int             pollfd_set_size;                // size of dynamically adjusted set 
    4444 
  • nebula/trunk/src/session.c

    r1611 r1612  
    3535 
    3636 
    37 void session_reset(submission *s, int session_number) { 
    38         if (!s) return; 
     37void session_reset(submission *subm, int session_number) { 
     38        if (!subm) return; 
    3939 
    4040        pthread_mutex_lock(&sessions_mutex); 
    4141 
    42         free(s->cattack); 
    43         free(s->attack); 
    44         free(s->md5sum); 
    45         free(s->hmac); 
    46         memset(s, 0, sizeof(submission)); 
    47  
    48         if (session_number >= 0 && pfdflag[session_number]) { 
     42        free(subm->cattack); 
     43        free(subm->attack); 
     44        free(subm->md5sum); 
     45        free(subm->hmac); 
     46        memset(subm, 0, sizeof(submission)); 
     47 
     48        if (session_number > 0) { 
    4949                if (pfdset[session_number].fd >= 0) close(pfdset[session_number].fd); 
    50                 if (verbose > 1) printf("[<] Connection terminated.\n"); 
    51  
    52                 // shrink pollfd set 
    53                 memmove(&pfdset[session_number], &pfdset[session_number+1], sizeof(struct pollfd) * (POLLFD_SET_SIZE-session_number)); 
     50                if (verbose > 1) printf("[<] Connection terminated: %d.\n", pfdset[session_number].fd); 
     51 
     52                // shrink pollfd set and adjust session array 
     53                memmove(&pfdset[session_number], &pfdset[session_number+1], sizeof(struct pollfd) * (pollfd_set_size-session_number)); 
     54                memmove(&s[session_number], &s[session_number+1], sizeof(submission) * (pollfd_set_size-session_number)); 
     55 
    5456                memset(&pfdset[pollfd_set_size], 0, sizeof(struct pollfd)); 
     57                memset(&s[pollfd_set_size], 0, sizeof(submission)); 
     58 
    5559                pollfd_set_size--; 
    56  
    57                 pfdset[session_number].events   = 0; 
    58                 pfdflag[session_number]         = 0;    // mark fd as unused 
    5960        } 
    6061 
     
    179180 
    180181                        if (s->state != AUTHENTICATED) { 
    181                                 printf("[x] Secret mismatch, dropping session.\n"); 
     182                                printf("[x] Secret mismatch, dropping session: %d.\n", pfd->fd); 
    182183                                fflush(stdout); 
    183184                                return(0); 
     
    201202                        pthread_rwlock_rdlock(&md5sum_trie_lock); 
    202203                        t = trie_find_memstr(&md5sum_trie, (u_char *) s->md5sum, strlen(s->md5sum)); 
    203                         pthread_rwlock_unlock(&md5sum_trie_lock); 
    204204 
    205205                        if (t != NULL) { 
     
    207207                                if (write(pfd->fd, "KNOWN\n", 6) == -1) { 
    208208                                        fprintf(stderr, "Error - Unable to send data request: %s.\n", strerror(errno)); 
     209                                        pthread_rwlock_unlock(&md5sum_trie_lock); 
    209210                                        return(-1); 
    210211                                } 
     
    212213                                // increase instance counter 
    213214                                ((hash*)t->data)->cnt++; 
     215                                pthread_rwlock_unlock(&md5sum_trie_lock); 
    214216                                if (verbose > 1) printf("    MD5 hash is %s (%u instances)\n", ((hash*)t->data)->md5sum, ((hash*)t->data)->cnt); 
    215217 
     
    219221                        } else { 
    220222                                // unknown attack hash, send request 
     223                                pthread_rwlock_unlock(&md5sum_trie_lock); 
    221224                                if (write(pfd->fd, "UNKNOWN\n", 8) == -1) { 
    222225                                        fprintf(stderr, "Error - Unable to send data request: %s.\n", strerror(errno)); 
  • nebula/trunk/src/session.h

    r1593 r1612  
    5858 
    5959typedef struct submission { 
    60         u_int32_t       session_number;         // session number in array 
    6160        sstate          state;                  // session state 
    6261        u_int32_t       bytes_read;             // number of bytes read so far 
  • nebula/trunk/src/sig.c

    r1611 r1612  
    174174 
    175175                // increase size threshold for this cluster 
    176                 sig->cl->threshold *= 1.5
     176                sig->cl->threshold *= 1.3
    177177 
    178178                free(sigdata); 
     
    186186                n->data = sig->cl; 
    187187                pthread_rwlock_unlock(&sighash_trie_lock); 
    188  
    189                 // increment size threshold 
    190                 if (sig->cl->threshold >= sig->cl->hq->size) sig->cl->threshold = sig->cl->hq->size; 
    191                 else sig->cl->threshold *= 1.1; 
    192188        } 
    193189        free(sigdata); 
  • nebula/trunk/src/signals.c

    r1588 r1612  
    7979        if (sig == SIGINT || sig == SIGTERM) { 
    8080                // free memory and quit 
     81                fflush(stdout); 
    8182                if (verbose) write(STDOUT_FILENO, "[*] Termination forced, cleaning up.\n", 37); 
    8283                cleanup(); 
     
    102103                SIGINT, 
    103104                SIGQUIT, 
    104               SIGSEGV, 
     105//            SIGSEGV, 
    105106                SIGTERM 
    106107        }; 
  • nebula/trunk/src/util.c

    r1582 r1612  
    108108        lock_mutex = 0; 
    109109 
     110        // close listening socket 
     111        shutdown(pfdset[0].fd, SHUT_RDWR); 
     112 
    110113        // close all open sessions 
    111         for (i = 0; i+1 < POLLFD_SET_SIZE; i++) 
    112                 if (pfdset[i].fd >= 0) shutdown(pfdset[i].fd, SHUT_RDWR); 
     114        for (i = 0; i <= POLLFD_MAX_SET_SIZE; i++) shutdown(pfdset[i].fd, SHUT_RDWR); 
    113115 
    114116        // free data structures