fix for bug 1200
authorsahlberg <sahlberg@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 7 Nov 2006 13:19:31 +0000 (13:19 +0000)
committersahlberg <sahlberg@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 7 Nov 2006 13:19:31 +0000 (13:19 +0000)
there used to be a bug in tcp reassembly that even if the dissector only asked for x more bytes from the next segment   the entire segment would still be added to reassembly.
this caused some issues when there was a new multisegment pdu that started at the end of the segment   but this bug was fixed when tcp reassembly was refactored semi-recently.

there was also another "bug" in the http reassembly that it would only ask for one more byte at a time when doing reassembly.
this did work well however when we still had the bug in tcp reassembly   but made wireshark become very very very slow once this tcp bug was fixed  since it is very very very slow to reassemble a huge http pdu just one byte at a time.

this patch adds partial support (what we need for http   which does not use tcp_dissect_pdus() ) for the desegmentation flag : DESEGMENT_ONE_MORE_SEGMENT and also to the http dissector   so that reassembly of http headers spanning multiple semgents now become fast again

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@19859 f5534014-38df-0310-8fa8-9805f1628bb7

epan/dissectors/packet-tcp.c
epan/dissectors/packet-tcp.h
epan/packet_info.h
epan/req_resp_hdrs.c

index ce1b3b75f6b26a9127d5a638e801b63fbbae020b..f1e2ab38274fa147409b2b0743685ef9964219ed 100644 (file)
@@ -378,6 +378,7 @@ pdu_store_sequencenumber_of_next_pdu(packet_info *pinfo, guint32 seq, guint32 nx
        msp->first_frame=pinfo->fd->num;
        msp->last_frame=pinfo->fd->num;
        msp->last_frame_time=pinfo->fd->abs_ts;
+       msp->flags=0;
        se_tree_insert32(tcpd->fwd->multisegment_pdus, seq, (void *)msp);
        return msp;
 }
@@ -1100,7 +1101,14 @@ again:
                /* OK, this PDU was found, which means the segment continues
                   a higher-level PDU and that we must desegment it.
                */
-               len=MIN(nxtseq, msp->nxtpdu) - seq;
+               if(msp->flags&MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT){
+                       /* The dissector asked for the entire segment */
+                       len=tvb_length_remaining(tvb, offset);
+                       msp->flags&=(~MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT);
+               } else {
+                       len=MIN(nxtseq, msp->nxtpdu) - seq;
+               }
+
                ipfd_head = fragment_add(tvb, offset, pinfo, msp->first_frame,
                        tcp_fragment_table,
                        seq - msp->seq,
@@ -1321,8 +1329,20 @@ again:
 
            if( ((nxtseq - deseg_seq) <= 1024*1024)
            &&  (!pinfo->fd->flags.visited) ){
-               msp = pdu_store_sequencenumber_of_next_pdu(pinfo, deseg_seq,
-                       nxtseq + pinfo->desegment_len, tcpd);
+               if(pinfo->desegment_len==DESEGMENT_ONE_MORE_SEGMENT){
+                       /* The subdissector asked to reassemble using the
+                        * entire next segment.
+                        * Just ask reassembly for one more byte
+                        * but set this msp flag so we can pick it up
+                        * above.
+                        */
+                       msp = pdu_store_sequencenumber_of_next_pdu(pinfo, 
+                               deseg_seq, nxtseq+1, tcpd);
+                       msp->flags|=MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT;
+               } else {
+                       msp = pdu_store_sequencenumber_of_next_pdu(pinfo, 
+                               deseg_seq, nxtseq+pinfo->desegment_len, tcpd);
+               }
 
                /* add this segment as the first one for this new pdu */
                fragment_add(tvb, deseg_offset, pinfo, msp->first_frame,
index 1ab5ee36aeb5a2e2ce904cfce3f501f530c16c37..911f565f0a9d32d2eee7c67076cad4770c7cf04f 100644 (file)
@@ -116,6 +116,8 @@ struct tcp_multisegment_pdu {
        guint32 first_frame;
        guint32 last_frame;
         nstime_t last_frame_time;
+       guint32 flags;
+#define MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT    0x00000001
 };
 
 typedef struct _tcp_flow_t {
index 43f2d673d3efc6acc33c6c22799fe96d40d06fad..46633e992a7f288f4ebac0436c4fff512c3ce7ed 100644 (file)
@@ -91,7 +91,7 @@ typedef struct _packet_info {
                                   or 
                                   DESEGMENT_ONE_MORE_SEGMENT:
                                     Desegment one more full segment 
-                                    (not yet implemented)
+                                    (warning! only partially implemented)
                                   DESEGMENT_UNTIL_FIN:
                                     Desgment all data for this tcp session 
                                     until the FIN segment.
index 5696c51558b38ede14d4bca14d8cf340a362c0e4..8d861ec62a6751b5a1c209806b6b833708cf49f9 100644 (file)
@@ -107,7 +107,7 @@ req_resp_hdrs_do_reassembly(tvbuff_t *tvb, int offset, packet_info *pinfo,
                         */
                        if (reported_length_remaining < 1) {
                                pinfo->desegment_offset = offset;
-                               pinfo->desegment_len = 1;
+                               pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
                                return FALSE;
                        }
 
@@ -124,7 +124,7 @@ req_resp_hdrs_do_reassembly(tvbuff_t *tvb, int offset, packet_info *pinfo,
                                 * byte.
                                 */
                                pinfo->desegment_offset = offset;
-                               pinfo->desegment_len = 1;
+                               pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
                                return FALSE;
                        } else if (linelen == 0) {
                                /*