inline void cx_track_simd_ipv4(packetinfo *pi) { connection *cxt = NULL; connection *head = NULL; uint32_t hash; // add to packetinfo ? dont through int32 around :) hash = make_hash(pi); cxt = bucket[hash]; head = cxt; ip6v incoming; ip6v compare; VEC_FILL(incoming, pi->ip_src.__u6_addr.__u6_addr32[0], pi->ip_dst.__u6_addr.__u6_addr32[0], pi->s_port, pi->d_port); while (cxt != NULL) { VEC_FILL(compare, cxt->s_ip.__u6_addr.__u6_addr32[0], cxt->d_ip.__u6_addr.__u6_addr32[0], cxt->s_port, cxt->d_port); // single-instruction compare -msse2 compare.v = __builtin_ia32_pcmpeqd128(incoming.v,compare.v); // same thing, really. c == v iff c ^ v == 0 //compare.v = compare.v ^ incoming.v; // 64-bit compare reduce if(!(compare.i[0] & compare.i[1])){ //ok dlog("[*] Updating src connection: %lu\n",cxt->cxid); cxt_update_src(cxt,pi); return; } // compare the other direction VEC_FILL(compare, cxt->d_ip.__u6_addr.__u6_addr32[0], cxt->s_ip.__u6_addr.__u6_addr32[0], cxt->d_port, cxt->s_port); compare.v = __builtin_ia32_pcmpeqd128(incoming.v,compare.v); if(!(compare.i[0] & compare.i[1])){ dlog("[*] Updating dst connection: %lu\n",cxt->cxid); cxt_update_dst(cxt,pi); return; } cxt = cxt->next; } if (cxt == NULL) { cxt = (connection *) connection_alloc(); //cxt = (connection *) calloc(1, sizeof(connection)); if (head != NULL) { head->prev = cxt; } cxt = cxt_new(pi); dlog("[*] New connection: %lu\n",cxt->cxid); cxt->next = head; bucket[hash] = cxt; return; } printf("[*] Error in session tracking...\n"); exit (1); }
inline void cxt_update (packetinfo *pi, uint32_t hash) { connection *cxt = NULL; int ret = 0; /* get our hash bucket and lock it */ cxtbucket *cb = &cxt_hash[hash]; /* see if the bucket already has a connection */ if (cb->cxt == NULL) { /* no, so get a new one */ cxt = cb->cxt = cxt_dequeue(&cxt_spare_q); if (cxt == NULL) { cxt = cb->cxt = connection_alloc(); if (cxt == NULL) { return; } } /* these are protected by the bucket lock */ cxt->hnext = NULL; cxt->hprev = NULL; /* got one, initialize and return */ cxt_new(cxt,pi); cxt_requeue(cxt, NULL, &cxt_est_q); cxt->cb = cb; cxt_update_src(cxt, pi); pi->cxt = cxt; return; } /* ok, we have a flow in the bucket. Let's find out if it is our flow */ cxt = cb->cxt; /* see if this is the flow we are looking for */ if (pi->af == AF_INET) { if (CMP_CXT4(cxt, PI_IP4SRC(pi), pi->s_port, PI_IP4DST(pi), pi->d_port)) { cxt_update_src(cxt, pi); ret = 1; } else if (CMP_CXT4(cxt, PI_IP4DST(pi), pi->d_port, PI_IP4SRC(pi), pi->s_port)) { cxt_update_dst(cxt, pi); ret = 1; } } else if (pi->af == AF_INET6){ if (CMP_CXT6(cxt, &PI_IP6SRC(pi), pi->s_port, &PI_IP6DST(pi), pi->d_port)) { cxt_update_src(cxt, pi); ret = 1; } else if (CMP_CXT6(cxt, &PI_IP6DST(pi), pi->d_port, &PI_IP6SRC(pi), pi->s_port)) { cxt_update_dst(cxt, pi); ret = 1; } } if (ret == 0) { connection *pcxt = NULL; /* previous connection */ while (cxt != NULL) { pcxt = cxt; /* pf is not locked at this point */ cxt = cxt->hnext; if (cxt == NULL) { /* get us a new one and put it and the list tail */ cxt = pcxt->hnext = cxt_dequeue(&cxt_spare_q); if (cxt == NULL) { cxt = cb->cxt = connection_alloc(); if (cxt == NULL) { return; } } cxt->hnext = NULL; cxt->hprev = pcxt; /* initialize and return */ cxt_new(cxt,pi); cxt_requeue(cxt, NULL, &cxt_est_q); cxt->cb = cb; cxt_update_src(cxt, pi); pi->cxt = cxt; return; } if (pi->af == AF_INET) { if (CMP_CXT4(cxt, PI_IP4SRC(pi), pi->s_port, PI_IP4DST(pi), pi->d_port)) { cxt_update_src(cxt, pi); ret = 1; } else if (CMP_CXT4(cxt, PI_IP4DST(pi), pi->d_port, PI_IP4SRC(pi), pi->s_port)) { cxt_update_dst(cxt, pi); ret = 1; } } else if (pi->af == AF_INET6) { if (CMP_CXT6(cxt, &PI_IP6SRC(pi), pi->s_port, &PI_IP6DST(pi), pi->d_port)) { cxt_update_src(cxt, pi); ret = 1; } else if (CMP_CXT6(cxt, &PI_IP6DST(pi), pi->d_port, &PI_IP6SRC(pi), pi->s_port)) { cxt_update_dst(cxt, pi); ret = 1; } } if ( ret != 0) { /* we found our flow, lets put it on top of the * hash list -- this rewards active flows */ if (cxt->hnext) cxt->hnext->hprev = cxt->hprev; if (cxt->hprev) cxt->hprev->hnext = cxt->hnext; cxt->hnext = cb->cxt; cxt->hprev = NULL; cb->cxt->hprev = cxt; cb->cxt = cxt; /* found our connection */ pi->cxt = cxt; return; } /* not found, try the next... */ } } pi->cxt = cxt; /* The 'root' connection was our connection, return it. */ return; }