コード例 #1
0
ファイル: worker.c プロジェクト: BillTheBest/opennop
void *worker_thread(void *dummyPtr) {
    struct processor *me = NULL;
    struct packet *thispacket = NULL;
    struct session *thissession = NULL;
    struct iphdr *iph = NULL;
    struct tcphdr *tcph = NULL;
    __u32 largerIP, smallerIP;
    __u16 largerIPPort, smallerIPPort;
    char *remoteID = NULL;
    char message[LOGSZ];
    qlz_state_compress *state_compress = (qlz_state_compress *) malloc(
                                             sizeof(qlz_state_compress));
    qlz_state_decompress *state_decompress = (qlz_state_decompress *) malloc(
                sizeof(qlz_state_decompress));
    me = (struct processor*) dummyPtr;

    me->lzbuffer = calloc(1, BUFSIZE + 400);
    /* Sharwan J: QuickLZ buffer needs (original data size + 400 bytes) buffer */

    if (me->lzbuffer == NULL) {
        sprintf(message, "Worker: Couldn't allocate buffer");
        logger(LOG_INFO, message);
        exit(1);
    }

    /*
     * Register the worker threads metrics so they get updated.
     */
    register_counter(counter_updateworkermetrics, (t_counterdata) & me->metrics);

    if (me->lzbuffer != NULL) {

        while (me->state >= STOPPING) {

            thispacket = dequeue_packet(&me->queue, true);

            if (thispacket != NULL) { // If a packet was taken from the queue.
                iph = (struct iphdr *) thispacket->data;
                tcph = (struct tcphdr *) (((u_int32_t *) iph) + iph->ihl);

                if (DEBUG_WORKER == true) {
                    sprintf(message, "Worker: IP Packet length is: %u\n",
                            ntohs(iph->tot_len));
                    logger(LOG_INFO, message);
                }
                me->metrics.bytesin += ntohs(iph->tot_len);

                //remoteID = (__u32) __get_tcp_option((__u8 *)iph,30);/* Check what IP address is larger. */
                remoteID = get_nod_header_data((__u8 *)iph, ONOP).data;

                sort_sockets(&largerIP, &largerIPPort, &smallerIP, &smallerIPPort,
                             iph->saddr,tcph->source,iph->daddr,tcph->dest);

                if (DEBUG_WORKER == true) {
                    sprintf(message, "Worker: Searching for session.\n");
                    logger(LOG_INFO, message);
                }

                thissession = getsession(largerIP, largerIPPort, smallerIP,smallerIPPort);

                if (thissession != NULL) {

                    if (DEBUG_WORKER == true) {
                        sprintf(message, "Worker: Found a session.\n");
                        logger(LOG_INFO, message);
                    }

                    if ((tcph->syn == 0) && (tcph->ack == 1) && (tcph->fin == 0)) {

                        if ((remoteID == NULL) || verify_neighbor_in_domain(remoteID) == false) {
                            /*
                             * An accelerator ID was NOT found.
                             * This is the first accelerator in the traffic path.
                             * This will soon be tested against a list of opennop neighbors.
                             * Traffic is sent through the optimize functions.
                             */

                            saveacceleratorid(largerIP, (char*)get_opennop_id(), iph, thissession);

                            //binary_dump("worker.c IP Packet: ", (char*)iph, ntohs(iph->tot_len));
                            //__set_tcp_option((__u8 *)iph,30,6,localID); // Add the Accelerator ID to this packet.
                            set_nod_header_data((__u8 *)iph, ONOP, get_opennop_id(), OPENNOP_IPC_ID_LENGTH);
                            //binary_dump("worker.c IP Packet: ", (char*)iph, ntohs(iph->tot_len));

                            if ((((iph->saddr == largerIP) &&
                                    //(thissession->larger.accelerator == localID) &&
                            		(compare_opennopid((char*)&thissession->larger.accelerator, (char*)get_opennop_id()) == 1) &&
                                    //(thissession->smaller.accelerator != 0) &&
                            		(check_opennopid((char*)&thissession->smaller.accelerator) == 1) &&
                                    //(thissession->smaller.accelerator != localID)) ||
                            		(compare_opennopid((char*)&thissession->smaller.accelerator, (char*)get_opennop_id()) != 1))
                            		||
                                    ((iph->saddr == smallerIP) &&
                                     //(thissession->smaller.accelerator == localID) &&
                                    (compare_opennopid((char*)&thissession->smaller.accelerator, (char*)get_opennop_id()) == 1) &&
                                     //(thissession->larger.accelerator != 0) &&
                                    (check_opennopid((char*)&thissession->larger.accelerator) == 1) &&
                                     //(thissession->larger.accelerator != localID))) &&
                                    (compare_opennopid((char*)&thissession->larger.accelerator, (char*)get_opennop_id()) != 1))) &&
                                    (thissession->state == TCP_ESTABLISHED)) {

                                /*
                                 * Do some acceleration!
                                 */

                                if (DEBUG_WORKER == true) {
                                    sprintf(message, "Worker: Compressing packet.\n");
                                    logger(LOG_INFO, message);
                                }
                                updateseq(largerIP, iph, tcph, thissession);
                                tcp_compress((__u8 *)iph, me->lzbuffer,state_compress);
                            } else {

                            	 updateseq(largerIP, iph, tcph, thissession);

                                if (DEBUG_WORKER == true) {
                                    sprintf(message, "Worker: Not compressing packet.\n");
                                    logger(LOG_INFO, message);
                                }
                            }
                            /*
                             * End of what should be the optimize function.
                             */
                        } else if(verify_neighbor_in_domain(remoteID) == true) {
                            /*
                             * An accelerator ID WAS found.
                             * Traffic is sent through the de-optimize functions.
                             */

                            saveacceleratorid(largerIP, remoteID, iph, thissession);

                            if (__get_tcp_option((__u8 *)iph,31) != 0) { // Packet is flagged as compressed.

                                if (DEBUG_WORKER == true) {
                                    sprintf(message, "Worker: Packet is compressed.\n");
                                    logger(LOG_INFO, message);
                                }

                                if (((iph->saddr == largerIP) &&
                                        //(thissession->smaller.accelerator == localID)) ||
                                		(compare_opennopid((char*)&thissession->smaller.accelerator, (char*)get_opennop_id()) == 1))||
                                        ((iph->saddr == smallerIP) &&
                                         //(thissession->larger.accelerator == localID))) {
                                        (compare_opennopid((char*)&thissession->larger.accelerator, (char*)get_opennop_id()) == 1))) {

                                    /*
                                     * Decompress this packet!
                                     */
                                    if (tcp_decompress((__u8 *)iph, me->lzbuffer, state_decompress) == 0) { // Decompression failed if 0.
                                        nfq_set_verdict(thispacket->hq, thispacket->id, NF_DROP, 0, NULL); // Decompression failed drop.
                                        put_freepacket_buffer(thispacket);
                                        thispacket = NULL;
                                    }else{
                                    	updateseq(largerIP, iph, tcph, thissession); // Only update the sequence after decompression.
                                    }
                                }
                            }else{
                            	updateseq(largerIP, iph, tcph, thissession); // Also update sequences if packet is not optimized.
                    		}
                            /*
                             * End of what should be the deoptimize function.
                             */
                        }
                    }

                    if (tcph->rst == 1) { // Session was reset.

                        if (DEBUG_WORKER == true) {
                            sprintf(message, "Worker: Session was reset.\n");
                            logger(LOG_INFO, message);
                        }
                        thissession = clearsession(thissession);
                    }

                    /* Normal session closing sequence. */
                    if (tcph->fin == 1) {
                        thissession = closingsession(tcph, thissession);
                    }

                    if (thispacket != NULL) {
                        /*
                         * Changing anything requires the IP and TCP
                         * checksum to need recalculated.
                         */
                        checksum(thispacket->data);
                        me->metrics.bytesout += ntohs(iph->tot_len);
                        nfq_set_verdict(thispacket->hq, thispacket->id, NF_ACCEPT, ntohs(iph->tot_len), (unsigned char *)thispacket->data);
                        put_freepacket_buffer(thispacket);
                        thispacket = NULL;
                    }

                } /* End NULL session check. */
                else { /* Session was NULL. */
                    me->metrics.bytesout += ntohs(iph->tot_len);
                    nfq_set_verdict(thispacket->hq, thispacket->id, NF_ACCEPT, 0, NULL);
                    put_freepacket_buffer(thispacket);
                    thispacket = NULL;
                }
                me->metrics.packets++;
            } /* End NULL packet check. */
        } /* End working loop. */
        free(me->lzbuffer);
        free(state_compress);
        free(state_decompress);
        me->lzbuffer = NULL;
    }
    return NULL;
}
コード例 #2
0
ファイル: mypool_tmp0331.c プロジェクト: jianglichi/code
void *thread_process() {
     int thisret,size,i,fields,j,bufout=0,counter=0;
	 int fetch_resu;
     long int datalen,buflen=0;
     int ociposi=-1;
     char buf[_buflen],tmp[_buflen],*realdata ;
     mytext *sqldata;
     int realdatalen=0;
     ub1   *bufp;
     int bufpint=1024;
     dvoid *hdlptr = (dvoid *) 0,*tmphdlptr = (dvoid *) 0;
     ub1   in_out = 0;
     sb2   indptr = 0;
     ub1   piece = OCI_FIRST_PIECE;
     ub4 	hdltype = OCI_HTYPE_DEFINE, iter = 0, idx = 0;
     int poid;
     pthread_detach(pthread_self());
     sqldata=(mytext *)malloc(sizeof(mytext));
     sqldata->next=0;
     sqldata->last=0;
     sqldata->size=0;
     bufp=(ub1 *)malloc(sizeof(ub1)*_clobmax);//**bufp must set to _clobmax
     
     realdata=(char *)malloc(_buflen);  
     realdatalen=_buflen;
     
     if((ociposi=getsession())==-1){
          printf("pool is busy!!\n");
          buf[16]=0;
          exit(1);
     }          
	 
	 
     poci[ociposi].threadid=pthread_self();    
     poci[ociposi].id=ociposi;
     printf("thread id=%d , ociposi=%d \n",pthread_self(),ociposi);
     memset(buf,0,_buflen);
     
			 
     while(1){
          pthread_mutex_lock(&mylock);
          thisret=accept(sock,NULL,NULL);
          pthread_mutex_unlock(&mylock);
          
          poci[ociposi].busy=1;
          bufout=0;
          conn_times++;
          if(conn_times>=1000000){conn_times1++;conn_times=0;}
          if(conn_times1>=1000000)conn_times1=0;
          printf("connections %d millions %d socket=%d ociposi=%d\n",conn_times1,conn_times,thisret,ociposi);
          
          poci[ociposi].datetime=datetime->tm_min*60+datetime->tm_sec;
          poci[ociposi].transfer=0;
          //data_buffer(sqldata,"",2,0);
	        while(sqldata->next){
	            sqldata=sqldata->next;
	        }
	        sqldata->size=0;
	        while(sqldata->last){
	            sqldata=sqldata->last;
	            sqldata->size=0;
	        }								   

          
          
          poci[ociposi].sock=thisret;
          
          
          
          while(size=recv(thisret,buf,_buflen,0)){
               buflen=size;
               buf[buflen]=0;
               poci[ociposi].transfer=1;
               //printf("--buflen=%d \n",buflen);
               
               if(buflen>2){
               }
               else{
                   bufout++;
                   if(bufout>=5 || buflen<=0)break;
               }
               size=buflen;
               if(poci[ociposi].sock==0)continue;
               poci[ociposi].datetime=datetime->tm_min*60+datetime->tm_sec;
               
               
               data_buffer(sqldata,buf,1,buflen);               
               
               //end
               j=0;
               if(size>9)
               for(i=size-9;i<size;i++){
                   tmp[j]=buf[i];
                   j++;
               }
               tmp[j]=0;          
               if((strncmp(buf,_end,strlen(_end))==0)||(strncmp(tmp,_end,strlen(_end))==0)){
                   break;
               }
          
               //set commit off
               if(strncmp(buf,_commitoff,strlen(_commitoff))==0){
                   poci[ociposi].commitmode=1;
                   memset(buf,0,sizeof(buf));
                   send(thisret,_autocommitoff,strlen(_autocommitoff),0);
                   continue;
               }
          
               //_commit
               if(strncmp(buf,_commit,strlen(_commit))==0){
                   OCITransCommit(poci[ociposi].svchp,poci[ociposi].errhp,OCI_DEFAULT );
                   memset(buf,0,sizeof(buf));
                   continue;
               }
                          
               //set commit on
               if(strncmp(buf,_commiton,strlen(_commiton))==0){              
                   poci[ociposi].commitmode=0;
                   memset(buf,0,sizeof(buf));
                   send(thisret,_autocommiton,strlen(_autocommiton),0);
                   continue;
               }                                                                              
               
               //rollback
               if(strncmp(buf,_rollback,strlen(_rollback))==0){
                   OCITransRollback(poci[ociposi].svchp,poci[ociposi].errhp,OCI_DEFAULT) ;
                   poci[ociposi].commitmode=1;
                   memset(buf,0,sizeof(buf));
                   continue;   
               }
               //_serverdown
               if(strncmp(buf,_serverdown,strlen(_serverdown))==0){
               	   OCITerminate(OCI_DEFAULT);
                   exit(1);
               }                    
          
          
               if(sqldata->size+1>=_mytextlen)
               while(sqldata->next){
                  if(sqldata->size+1>=_mytextlen)
                     sqldata=sqldata->next;
                  else
                     break;
               }
               //end input
               size=sqldata->size;
               datalen=size-2; 
               j=0;
               if(size>15)
               for(i=size-15;i<size;i++){
                   tmp[j]=sqldata->mydata[i];
                   j++;
               }
               tmp[j]=0;
               if((strncmp(tmp,_inputend,strlen(_inputend))==0)){    
                   datalen=data_buffer(sqldata,buf,3,0);
                   if(datalen+1>realdatalen){
                       printf("free\n");
                       free(realdata);
                       printf("malloc\n");
                       realdata=(char *)malloc(datalen+1); 
                       realdatalen=datalen+1;
                   }
                   data_buffer(sqldata,realdata,4,0);
                   
                   size=realdatalen;
                   realdata[size-17]=0;          
                   
				   
                   OCIHandleAlloc(poci[ociposi].envhp,(dvoid*)&poci[ociposi].stmthp,OCI_HTYPE_STMT,0,0);
				   
				   printf("oracle_query \n");
                   fields=oracle_query(&poci[ociposi],realdata,datalen-17,tmp);
				   printf("oracle_query ok fields=%d \n",fields);
				   
				   if(fields<=0)break;
                   //printf("start fetch\n");
                   i=0;
				   counter=0;
                   if(fields>0){
                       piece = OCI_FIRST_PIECE ;
                       bufp[0]=0;
                       fetch_data(&poci[ociposi]);
					   counter++;printf("counter=%d \n",counter);
                       send_process(_output_begin,strlen(_output_begin),&poci[ociposi]);
                       
                       while (poci[ociposi].status != OCI_NO_DATA){
               	           //if(OCI_NEED_DATA==poci[ociposi].status){
	               	           //bufpint=4096;
	                           //poci[ociposi].status = OCIStmtGetPieceInfo(poci[ociposi].stmthp, poci[ociposi].errhp, &hdlptr, &hdltype,&in_out, &iter, &idx, &piece);
	                           //poci[ociposi].status = OCIStmtSetPieceInfo(hdlptr, hdltype, poci[ociposi].errhp,(dvoid *) bufp, &bufpint, piece,(CONST dvoid *) &indptr, (ub2 *) 0);
							   
						   //}
						   
						   //printf("data=%s\n",poci[ociposi].data[0]);
						   //printf("data=%s\n",poci[ociposi].data[1]);
						   //printf("data=%s\n",poci[ociposi].data[2]);
						   
						   fetch_data(&poci[ociposi]);
						   if(poci[ociposi].status<0)break;
						   
						   counter++;printf("OCI_NO_DATA=%d , poci[ociposi].status=%d , counter=%d fetch_resu=%d \n",OCI_NO_DATA,poci[ociposi].status,counter);
						   bufp[bufpint]=0;
						   
						   
							for (i=0;i<fields;i++){
								send_process(poci[ociposi].data[i],strlen(poci[ociposi].data[i]),&poci[ociposi]);
								if(i+1<fields){
									send_process(_output_column,strlen(_output_column),&poci[ociposi]);
								}
							}
						    send_process(_output_row,strlen(_output_row),&poci[ociposi]);
						   /*
						   if(poci[ociposi].status==OCI_NEED_DATA){
								if(tmphdlptr!=hdlptr){
								  i++;
							  if(i>1)
							  if((i-1)%fields==0){
								  send_process(_output_row,strlen(_output_row),&poci[ociposi]);
							   }else{
								  send_process(_output_column,strlen(_output_column),&poci[ociposi]);
							   }
							   tmphdlptr=hdlptr;
							   }
							   send_process(bufp,bufpint,&poci[ociposi]);
						   }*/
                       	}
                       	
                       	if(i>1){
                       		send_process(_output_column,strlen(_output_column),&poci[ociposi]);
                       		send_process(bufp,bufpint,&poci[ociposi]);
                       		send_process(_output_row,strlen(_output_row),&poci[ociposi]);
                       	}
                       	send_process(_output_end,strlen(_output_end),&poci[ociposi]);
                   }else{
                      if((fields<0) && (strlen(poci[ociposi].errbuf)>0)){
                      	   send_process(_output_beginerr,strlen(_output_beginerr),&poci[ociposi]);
                           send_process(poci[ociposi].errbuf,512,&poci[ociposi]);
                           send_process(_output_end,strlen(_output_end),&poci[ociposi]);
                      }else{
                           send_process(_ok,strlen(_ok),&poci[ociposi]);
                      }
                   }
                   
                   OCIHandleFree(poci[ociposi].stmthp,OCI_HTYPE_STMT);
                   //printf("fetch ok\n");                                                         
                   send_process("",-1,&poci[ociposi]);
								   //printf("data send ok\n");
						       datalen=0;
								   //data_buffer(sqldata,"",2,0);
						        while(sqldata->next){
						            sqldata=sqldata->next;
						        }
						        sqldata->size=0;
						        while(sqldata->last){
						            sqldata=sqldata->last;
						            sqldata->size=0;
						        }								   
								   //printf("query complete\n");
		               
               }
               poci[ociposi].transfer=0;
          }
          close(thisret);
          poci[ociposi].busy=0;
		  if(fields==-99){
			poci[ociposi].id=-1;
			OCILogoff(poci[ociposi].svchp,poci[ociposi].errhp);
			OCIHandleFree(poci[ociposi].envhp,OCI_HTYPE_ENV);
			
			pthread_create(&ph[ociposi], NULL, &thread_process,NULL);
			printf("exit program \n");
			break;
		  
		  }
    }   

}
コード例 #3
0
ファイル: fetcher.c プロジェクト: solowan/solowan
int fetcher_callback(struct nfq_q_handle *hq, struct nfgenmsg *nfmsg,
		struct nfq_data *nfa, void *data) {
	u_int32_t id = 0;
	struct iphdr *iph = NULL;
	struct tcphdr *tcph = NULL;
	struct session *thissession = NULL;
	struct packet *thispacket = NULL;
	struct nfqnl_msg_packet_hdr *ph;
	struct timeval tv;
	__u32 largerIP, smallerIP, remoteID;
	__u16 largerIPPort, smallerIPPort, mms;
	int ret;
	int incomingQueueNum;
	unsigned char *originalpacket = NULL;
	char strIP[20];

    // for debugging purposes
    char saddr[INET_ADDRSTRLEN];
    char daddr[INET_ADDRSTRLEN];

	ph = nfq_get_msg_packet_hdr(nfa);

	if (ph) {
		id = ntohl(ph->packet_id);
	}

	ret = nfq_get_payload(nfa, &originalpacket);

	if (servicestate >= RUNNING) {

		iph = (struct iphdr *) originalpacket;

		thefetcher.metrics.bytesin += ntohs(iph->tot_len);

		/* We need to double check that only TCP packets get accelerated. */
		/* This is because we are working from the Netfilter QUEUE. */
		/* User could QUEUE UDP traffic, and we cannot accelerate UDP. */
		if ((iph->protocol == IPPROTO_TCP) && (id != 0)) {

			tcph = (struct tcphdr *) (((u_int32_t *) originalpacket) + iph->ihl);

            // for debugging purpose
			inet_ntop(AF_INET, &iph->saddr, saddr, INET_ADDRSTRLEN);
			inet_ntop(AF_INET, &iph->daddr, daddr, INET_ADDRSTRLEN);

			/* Check what IP address is larger. */
			sort_sockets(&largerIP, &largerIPPort, &smallerIP, &smallerIPPort,
					iph->saddr, tcph->source, iph->daddr, tcph->dest);

			// remoteID = (__u32) __get_tcp_option((__u8 *)originalpacket,32);
			if (__get_tcp_option((__u8 *)originalpacket,32) ) {
				unsigned char *tcpdata =  (unsigned char *) tcph + tcph->doff * 4; // Find starting location of the TCP data.
				unsigned int incLen   = (__u16)(ntohs(iph->tot_len) - iph->ihl * 4) - tcph->doff * 4;
				if (incLen < sizeof(OpennopHeader)) {
					LOGERROR(lc_fetcher, "detected opennop option but incoming TCP data length less than opennop header length!!!!");
					return nfq_set_verdict(hq, id, NF_DROP,0,NULL);
				}

				pOpennopHeader oh = (pOpennopHeader) tcpdata;
				remoteID = oh->opennopID;
				incomingQueueNum = oh->queuenum;
				if (oh->pattern != OPENNOP_PATTERN) {
					LOGERROR(lc_fetcher, "option 32 found but bad pattern!!!");
					return nfq_set_verdict(hq, id, NF_DROP,0,NULL);
				}
			} else remoteID = 0;

			inet_ntop(AF_INET, &remoteID, strIP, INET_ADDRSTRLEN);
			//LOGDEBUG(lc_fetcher, "The accellerator ID is:%s", strIP);

			if (remoteID == 0) { 
			    LOGTRACE(lc_fetcher, "Packet from CLIENT: SYN=%d/FIN=%d/ACK=%d/RST=%d, %s:%d->%s:%d, IP_Id=%d, NFQ_Id=%d, TCP_seq=%u, ACK_seq=%u, Total_len=%d, TCP_hlen=%d, IP_hlen=%d, Data_len=%d", 
                  tcph->syn, tcph->fin, tcph->ack, tcph->rst, saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest), ntohs(iph->id), id, ntohl(tcph->seq), ntohl(tcph->ack_seq),
                  ntohs(iph->tot_len), tcph->doff * 4, iph->ihl * 4, ntohs(iph->tot_len) - tcph->doff * 4 - iph->ihl * 4);
            } else {
			    LOGTRACE(lc_fetcher, "Packet from %s: SYN=%d/FIN=%d/ACK=%d/RST=%d, %s:%d->%s:%d, IP_Id=%d, NFQ_Id=%d, TCP_seq=%u, ACK_seq=%u, Total_len=%d, TCP_hlen=%d, IP_hlen=%d, Data_len=%d", 
                  strIP, tcph->syn, tcph->fin, tcph->ack, tcph->rst, saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest), ntohs(iph->id), id, ntohl(tcph->seq), ntohl(tcph->ack_seq),
                  ntohs(iph->tot_len), tcph->doff * 4, iph->ihl * 4, ntohs(iph->tot_len) - tcph->doff * 4 - iph->ihl * 4);
            }    

			thissession = getsession(largerIP, largerIPPort, smallerIP, smallerIPPort); // Check for an outstanding syn.

				// if (thissession != NULL) {
                //     LOGDEBUG(lc_sesman_check, "****** [SESSION MANAGER] LargerIPseq: %u SmallerIPseq %u, TCP_seq=%u", thissession->largerIPseq, thissession->smallerIPseq, ntohl(tcph->seq));
                // }

			/* Check if this a SYN packet to identify a new session. */
			/* This packet will not be placed in a work queue, but  */
			/* will be accepted here because it does not have any data. */
			//if ((tcph->syn == 1) && (tcph->ack == 0)) {
            
			if (tcph->syn == 1) {
                
                //
                // SYN segment
                //
                if (tcph->ack == 0) {
					if (remoteID == 0) { LOGDEBUG(lc_fetcher, "SYN from CLIENT: %s:%d->%s:%d", saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest) ); }
        	        else               { LOGDEBUG(lc_fetcher, "SYN from %s: %s:%d->%s:%d", strIP, saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest) ); }
				} else {
					if (remoteID == 0) { LOGDEBUG(lc_fetcher, "SYN+ACK from CLIENT: %s:%d->%s:%d", saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest) ); } 
					else               { LOGDEBUG(lc_fetcher, "SYN+ACK from %s: %s:%d->%s:%d", strIP, saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest) ); }
				}

				if (thissession == NULL) {
					if (remoteID != 0) thissession = insertsession(largerIP, largerIPPort, smallerIP, smallerIPPort, incomingQueueNum); // Insert into sessions list.
					else thissession = insertsession(largerIP, largerIPPort, smallerIP, smallerIPPort, -1); // Insert into sessions list.
					if (remoteID == 0) { LOGDEBUG(lc_fetcher, "New session from CLIENT created: %s:%d->%s:%d", saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest) ) }
                    else               { LOGDEBUG(lc_fetcher, "New session from %s created: %s:%d->%s:%d", strIP, saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest) ) };
				}

				/* We need to check for NULL to make sure */
				/* that a record for the session was created */
				if (thissession != NULL) {

					gettimeofday(&tv,NULL); // Get the time from hardware.
					thissession->lastactive = tv.tv_sec; // Update the session timestamp.

					sourceisclient(largerIP, iph, thissession, tcph->ack == 0);
					updateseq(largerIP, iph, tcph, thissession);
					updateseqnumber(largerIP, iph, tcph, thissession);

					if (remoteID == 0) { // Accelerator ID was not found.

						mms = __get_tcp_option((__u8 *)originalpacket,2);

						if (mms > 68) {

							if (__set_tcp_option((__u8 *)originalpacket,2,4,mms - 68) == -1) {// Reduce the MSS.
								LOGERROR(lc_fetcher, "Cannot reduce MSS in 68, fetcher.c, packet is a SYN, IP datagram ID %x, current value of TCP doff %d",ntohs(iph->id), tcph->doff);
							} 
							if (__set_tcp_option((__u8 *)originalpacket,32,3,1) == -1) { // Add the Accelerator ID to this packet.
								LOGERROR(lc_fetcher, "Cannot set opennop option to 1, fetcher.c, packet is a SYN, IP datagram ID %x, current value of TCP doff %d",ntohs(iph->id), tcph->doff);
							} else {
								unsigned char *tcpdata =  (unsigned char *) tcph + tcph->doff * 4; // Find starting location of the TCP data.
								pOpennopHeader oh = (pOpennopHeader) tcpdata;
								oh->opennopID = localID;
								oh->seqNo = 0;
								oh->compression = 0;
								oh->deduplication = 0;
								oh->reasonForNoOptimization = NOT_RELEVANT;
								oh->pattern = OPENNOP_PATTERN;
								oh->queuenum = thissession->queue;
								iph->tot_len = htons(ntohs(iph->tot_len)+sizeof(OpennopHeader));
								LOGTRACE(lc_fetcher, "Adding opennop header to SYN packet: IP total length=%d",ntohs(iph->tot_len));
							}

							saveacceleratorid(largerIP, localID, iph, thissession);

							/*
							 * Changing anything requires the IP and TCP
							 * checksum to need recalculated.
							 */
							checksum(originalpacket);
						}
					} else { // Accelerator ID was found.

					    //LOGDEBUG(lc_fetcher, "New session from %s created: %s:%d->%s:%d", strIP, saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest) );

						if (__set_tcp_option((__u8 *)originalpacket,32,3,0) == -1) { 
							LOGERROR(lc_fetcher, "Cannot set opennop option to 0, fetcher.c, packet is a SYN, IP datagram ID %x, current value of TCP doff %d",ntohs(iph->id), tcph->doff);
						} else iph->tot_len = htons(ntohs(iph->tot_len)-sizeof(OpennopHeader));
						checksum(originalpacket);
						saveacceleratorid(largerIP, remoteID, iph, thissession);

					}

                    if (tcph->ack == 0) {
					    thissession->state = TCP_SYN_SENT;
                        LOGDEBUG(lc_fetcher, "Session state set to TCP_SYN_SENT");
                    } else {
						thissession->state = TCP_ESTABLISHED;
                        LOGDEBUG(lc_fetcher, "Session state set to TCP_ESTABLISHED");
                    }
				}

				/* Before we return let increment the packets counter. */
				thefetcher.metrics.packets++;

				/* This is the last step for a SYN packet. */
				/* accept all SYN packets. */
				return nfq_set_verdict(hq, id, NF_ACCEPT, ntohs(iph->tot_len), (unsigned char *)originalpacket);

			// } else if (tcph->rst == 1) { 
                
                //
                // RESET segment
                //
                // LOGDEBUG(lc_fetcher, "Session RESET %s:%d->%s:%d", saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest));
                // clearsession(thissession);
		// fruiz // 
		// thissession = NULL;

                /* Before we return let increment the packets counter. */
				// thefetcher.metrics.packets++;
			    // return nfq_set_verdict(hq, id, NF_ACCEPT, 0, NULL);


//			} else if (tcph->fin == 1) {  
//                
//                //
//                // FIN segment
//                //
//                LOGDEBUG(lc_fetcher, "FIN packet: %s:%d->%s:%d", saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest));
//				if (thissession != NULL) {
//                    switch (thissession->state) {
//                        case TCP_ESTABLISHED:
//                                thissession->state = TCP_CLOSING;
//                                LOGDEBUG(lc_fetcher, "Session half closed: %s:%d->%s:%d", saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest));
//                                break;
//                        case TCP_CLOSING:
//                                clearsession(thissession);
//                                LOGDEBUG(lc_fetcher, "Session full closed: %s:%d->%s:%d", saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest));
//                                break;
//                    }
//                }
//
//                /* Before we return let increment the packets counter. */
//				thefetcher.metrics.packets++;
//	LOGDEBUG(lc_fetcher, "hq=%d, id=%d", hq, id);
//                int res = nfq_set_verdict(hq, id, NF_ACCEPT, ntohs(iph->tot_len), (unsigned char *)originalpacket);
//                LOGDEBUG(lc_fetcher, "Returning FIN packet %d", res);
//			    //return nfq_set_verdict(hq, id, NF_ACCEPT, 0, NULL);
//				//return nfq_set_verdict(hq, id, NF_ACCEPT, ntohs(iph->tot_len), (unsigned char *)originalpacket);
//				return res;


			} else { 

                //
                // DATA or FIN segment
                //
				if (thissession != NULL) { // DATA segment in an active session

                    //LOGDEBUG(lc_sesman_check, "[SESSION MANAGER] LargerIPseq: %u SmallerIPseq %u", thissession->largerIPseq, thissession->smallerIPseq);

					gettimeofday(&tv,NULL); // Get the time from hardware.
					thissession->lastactive = tv.tv_sec; // Update the active timer.
					thissession->deadcounter = 0; // Reset the dead counter.

					if (__get_tcp_option((__u8 *)originalpacket,32) == 2) { // Keepalive, can drop
						LOGDEBUG(lc_fetcher, "Received keepalive: %s:%d->%s:%d", saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest) );
						return nfq_set_verdict(hq, id, NF_DROP,0,NULL);
					}

					thispacket = get_freepacket_buffer();

					if (thispacket != NULL){
						save_packet(thispacket,hq, id, ret, (__u8 *)originalpacket, thissession);

						if (remoteID == 0){
						    LOGTRACE(lc_fetcher, "Packet sent to optimize");
							optimize_packet(thissession->queue, thispacket);
						} else {
						    LOGTRACE(lc_fetcher, "Packet sent to deoptimize");
							deoptimize_packet(thissession->queue, thispacket);
						}

					} else {
						LOGERROR(lc_fetcher, "Failed getting packet buffer for processing");
					}
					/* Before we return let increment the packets counter. */
					thefetcher.metrics.packets++;
					return 0;

				} else { // DATA segment and no active session exists


                    int data_len = ntohs(iph->tot_len) - tcph->doff * 4 - iph->ihl * 4;
                    if (data_len > 0) {
                        LOGDEBUG(lc_fetcher, "No session found for: SYN=%d/FIN=%d/ACK=%d/RST=%d, %s:%d->%s:%d, Opt_ID=%s, IP_Id=%d, NFQ_Id=%d, Total_len=%d, TCP_hlen=%d, IP_hlen=%d, Data_len=%d", 
                                tcph->syn, tcph->fin, tcph->ack, tcph->rst, saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest), strIP, ntohs(iph->id), id, 
                                ntohs(iph->tot_len), tcph->doff * 4, iph->ihl * 4, ntohs(iph->tot_len) - tcph->doff * 4 - iph->ihl * 4);
                    }

    				/* We only want to create new sessions for active sessions. */
    				/* This means we exclude anything accept ACK packets. */

    				if (tcph->ack == 1) {

    					if (remoteID != 0) { // Detected remote Accelerator so it is safe to add this session.
    						thissession = insertsession(largerIP, largerIPPort, smallerIP, smallerIPPort, incomingQueueNum); // Insert into sessions list.

   							if (thissession != NULL) { // Test to make sure the session was added.
					            
                                LOGDEBUG(lc_fetcher, "Created NEW session for: %s:%d->%s:%d", saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest) );

							    thissession->state = TCP_ESTABLISHED;

							    saveacceleratorid(largerIP, remoteID, iph, thissession);

							    thispacket = get_freepacket_buffer();

							    if (thispacket != NULL){
								    save_packet(thispacket,hq, id, ret, (__u8 *)originalpacket, thissession);
								    updateseqnumber(largerIP, iph, tcph, thissession); //Update the stored TCP sequence number
								    deoptimize_packet(thissession->queue, thispacket);
							    } else {
								    LOGERROR(lc_fetcher, "Failed getting packet buffer for deoptimization.");
							    }
							    /* Before we return let increment the packets counter. */
							    thefetcher.metrics.packets++;
							    return 0;
                            } else {
                                LOGERROR(lc_fetcher, "Failed to create session for: %s:%d->%s:%d", saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest) );
                            }
                        }
				    }
					/* Before we return let increment the packets counter. */
					thefetcher.metrics.packets++;
                    //LOGERROR(lc_fetcher, "Unknown packet: %s:%d->%s:%d", saddr, ntohs(tcph->source), daddr, ntohs(tcph->dest) );
					return nfq_set_verdict(hq, id, NF_ACCEPT, ntohs(iph->tot_len), (unsigned char *)originalpacket);
			    }
			}
		} else { /* Packet was not a TCP Packet or ID was 0. */