@ -105,6 +105,7 @@ typedef struct AppLayerParserProtoCtx_
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    int  ( * StateGetProgress ) ( void  * alstate ,  uint8_t  direction ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    uint64_t  ( * StateGetTxCnt ) ( void  * alstate ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    void  * ( * StateGetTx ) ( void  * alstate ,  uint64_t  tx_id ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    AppLayerGetTxIteratorFunc  StateGetTxIterator ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    int  ( * StateGetProgressCompletionStatus ) ( uint8_t  direction ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    int  ( * StateGetEventInfo ) ( const  char  * event_name , 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                             int  * event_id ,  AppLayerEventType  * event_type ) ; 
 
			
		 
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
			
			 
			 
			
				@ -518,6 +519,14 @@ void AppLayerParserRegisterGetTx(uint8_t ipproto, AppProto alproto,
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    SCReturn ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				void  AppLayerParserRegisterGetTxIterator ( uint8_t  ipproto ,  AppProto  alproto , 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                      AppLayerGetTxIteratorFunc  Func ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				{ 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    SCEnter ( ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    alp_ctx . ctxs [ FlowGetProtoMapping ( ipproto ) ] [ alproto ] . StateGetTxIterator  =  Func ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    SCReturn ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				void  AppLayerParserRegisterGetStateProgressCompletionStatus ( AppProto  alproto , 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    int  ( * StateGetProgressCompletionStatus ) ( uint8_t  direction ) ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				{ 
 
			
		 
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
			
			 
			 
			
				@ -609,6 +618,49 @@ void AppLayerParserDestroyProtocolParserLocalStorage(uint8_t ipproto, AppProto a
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    SCReturn ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				/** \brief default tx iterator
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 * 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 *   Used  if  the  app  layer  parser  doesn ' t  register  its  own  iterator . 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 *   Simply  walks  the  tx_id  space  until  it  finds  a  tx .  Uses  ' state '  to 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 *   keep  track  of  where  it  left  off . 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 * 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 *   \ retval  txptr  or  NULL  if  no  more  txs  in  list 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				 */ 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				static  AppLayerGetTxIterTuple  AppLayerDefaultGetTxIterator ( 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        const  uint8_t  ipproto ,  const  AppProto  alproto , 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        void  * alstate ,  uint64_t  min_tx_id ,  uint64_t  max_tx_id , 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        AppLayerGetTxIterState  * state ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				{ 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    uint64_t  ustate  =  * ( uint64_t  * ) state ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    uint64_t  tx_id  =  MAX ( min_tx_id ,  ustate ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    for  (  ;  tx_id  <  max_tx_id ;  tx_id + + )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        void  * tx_ptr  =  AppLayerParserGetTx ( ipproto ,  alproto ,  alstate ,  tx_id ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        if  ( tx_ptr  ! =  NULL )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            ustate  =  tx_id  +  1 ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            * state  =  * ( AppLayerGetTxIterState  * ) & ustate ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            AppLayerGetTxIterTuple  tuple  =  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                . tx_ptr  =  tx_ptr , 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                . tx_id  =  tx_id , 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                . has_next  =  ( tx_id  +  1  <  max_tx_id ) , 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            } ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            SCLogDebug ( " tulpe: %p/% " PRIu64 " /%s " ,  tuple . tx_ptr ,  tuple . tx_id , 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    tuple . has_next  ?  " true "  :  " false " ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            return  tuple ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    AppLayerGetTxIterTuple  no_tuple  =  {  NULL ,  0 ,  false  } ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    return  no_tuple ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				AppLayerGetTxIteratorFunc  AppLayerGetTxIterator ( const  uint8_t  ipproto , 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        const  AppProto  alproto ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				{ 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    AppLayerGetTxIteratorFunc  Func  = 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        alp_ctx . ctxs [ FlowGetProtoMapping ( ipproto ) ] [ alproto ] . StateGetTxIterator ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    return  Func  ?  Func  :  AppLayerDefaultGetTxIterator ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				} 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				void  AppLayerParserSetTxLogged ( uint8_t  ipproto ,  AppProto  alproto , 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                               void  * alstate ,  void  * tx ,  LoggerId  logger ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				{ 
 
			
		 
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
			
			 
			 
			
				@ -677,28 +729,37 @@ void AppLayerParserSetTransactionInspectId(const Flow *f, AppLayerParserState *p
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    const  uint8_t  ipproto  =  f - > proto ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    const  AppProto  alproto  =  f - > alproto ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    AppLayerGetTxIteratorFunc  IterFunc  =  AppLayerGetTxIterator ( ipproto ,  alproto ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    AppLayerGetTxIterState  state ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    memset ( & state ,  0 ,  sizeof ( state ) ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    SCLogDebug ( " called: %s, tag_txs_as_inspected %s " , direction = = 0 ? " toserver " : " toclient " , 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            tag_txs_as_inspected ? " true " : " false " ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    /* mark all txs as inspected if the applayer progress is
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				     *  at  the  ' end  state ' .  */ 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    for  ( ;  idx  <  total_txs ;  idx + + )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        void  * tx  =  AppLayerParserGetTx ( ipproto ,  alproto ,  alstate ,  idx ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        if  ( tx  = =  NULL ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            continue ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    while  ( 1 )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        AppLayerGetTxIterTuple  ires  =  IterFunc ( ipproto ,  alproto ,  alstate ,  idx ,  total_txs ,  & state ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        if  ( ires . tx_ptr  = =  NULL ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            break ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        void  * tx  =  ires . tx_ptr ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        idx  =  ires . tx_id ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        int  state_progress  =  AppLayerParserGetStateProgress ( ipproto ,  alproto ,  tx ,  flags ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        if  ( state_progress  > =  state_done_progress )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            if  ( tag_txs_as_inspected )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                uint64_t  detect_flags  =  AppLayerParserGetTxDetectFlags ( ipproto ,  alproto ,  tx ,  flags ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                if  ( ( detect_flags  &  APP_LAYER_TX_INSPECTED_FLAG )  = =  0 )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    detect_flags  | =  APP_LAYER_TX_INSPECTED_FLAG ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    AppLayerParserSetTxDetectFlags ( ipproto ,  alproto ,  tx ,  flags ,  detect_flags ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    SCLogDebug ( " %p/% " PRIu64 "  in-order tx is done for direction %s. Flag %016 " PRIx64 , 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                            tx ,  idx ,  flags  &  STREAM_TOSERVER  ?  " toserver "  :  " toclient " ,  detect_flags ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        if  ( state_progress  <  state_done_progress ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            break ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        if  ( tag_txs_as_inspected )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            uint64_t  detect_flags  =  AppLayerParserGetTxDetectFlags ( ipproto ,  alproto ,  tx ,  flags ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            if  ( ( detect_flags  &  APP_LAYER_TX_INSPECTED_FLAG )  = =  0 )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                detect_flags  | =  APP_LAYER_TX_INSPECTED_FLAG ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                AppLayerParserSetTxDetectFlags ( ipproto ,  alproto ,  tx ,  flags ,  detect_flags ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                SCLogDebug ( " %p/% " PRIu64 "  in-order tx is done for direction %s. Flag %016 " PRIx64 , 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        tx ,  idx ,  flags  &  STREAM_TOSERVER  ?  " toserver "  :  " toclient " ,  detect_flags ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            continue ;  
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        }  else 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        if  ( ! ires . has_next ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            break ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    pstate - > inspect_id [ direction ]  =  idx ; 
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -707,29 +768,39 @@ void AppLayerParserSetTransactionInspectId(const Flow *f, AppLayerParserState *p
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    /* if necessary we flag all txs that are complete as 'inspected'
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				     *  also  move  inspect_id  forward .  */ 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    if  ( tag_txs_as_inspected )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        for  ( ;  idx  <  total_txs ;  idx + + )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            bool  check_inspect_id  =  false ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            void  * tx  =  AppLayerParserGetTx ( ipproto ,  alproto ,  alstate ,  idx ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            if  ( tx  = =  NULL )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                check_inspect_id  =  true ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            }  else  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                int  state_progress  =  AppLayerParserGetStateProgress ( ipproto ,  alproto ,  tx ,  flags ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                if  ( state_progress  > =  state_done_progress )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    uint64_t  detect_flags  =  AppLayerParserGetTxDetectFlags ( ipproto ,  alproto ,  tx ,  flags ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    if  ( ( detect_flags  &  APP_LAYER_TX_INSPECTED_FLAG )  = =  0 )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        detect_flags  | =  APP_LAYER_TX_INSPECTED_FLAG ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        AppLayerParserSetTxDetectFlags ( ipproto ,  alproto ,  tx ,  flags ,  detect_flags ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        SCLogDebug ( " %p/% " PRIu64 "  out of order tx is done for direction %s. Flag %016 " PRIx64 , 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                                tx ,  idx ,  flags  &  STREAM_TOSERVER  ?  " toserver "  :  " toclient " ,  detect_flags ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        check_inspect_id  =  true ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        /* continue at idx */ 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        while  ( 1 )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            AppLayerGetTxIterTuple  ires  =  IterFunc ( ipproto ,  alproto ,  alstate ,  idx ,  total_txs ,  & state ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            if  ( ires . tx_ptr  = =  NULL ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                break ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            void  * tx  =  ires . tx_ptr ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            /* if we got a higher id than the minimum we requested, we
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				             *  skipped  a  bunch  of  ' null - txs ' .  Lets  see  if  we  can  up  the 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				             *  inspect  tracker  */ 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            if  ( ires . tx_id  >  idx  & &  pstate - > inspect_id [ direction ]  = =  idx )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                pstate - > inspect_id [ direction ]  =  ires . tx_id ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            if  ( check_inspect_id )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                SCLogDebug ( " %p/% " PRIu64 "  out of order tx. Update inspect_id? % " PRIu64 ,  tx ,  idx ,  pstate - > inspect_id [ direction ] ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            idx  =  ires . tx_id ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            const  int  state_progress  =  AppLayerParserGetStateProgress ( ipproto ,  alproto ,  tx ,  flags ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            if  ( state_progress  <  state_done_progress ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                break ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            uint64_t  detect_flags  =  AppLayerParserGetTxDetectFlags ( ipproto ,  alproto ,  tx ,  flags ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            if  ( ( detect_flags  &  APP_LAYER_TX_INSPECTED_FLAG )  = =  0 )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                detect_flags  | =  APP_LAYER_TX_INSPECTED_FLAG ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                AppLayerParserSetTxDetectFlags ( ipproto ,  alproto ,  tx ,  flags ,  detect_flags ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                SCLogDebug ( " %p/% " PRIu64 "  out of order tx is done for direction %s. Flag %016 " PRIx64 , 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        tx ,  idx ,  flags  &  STREAM_TOSERVER  ?  " toserver "  :  " toclient " ,  detect_flags ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                SCLogDebug ( " %p/% " PRIu64 "  out of order tx. Update inspect_id? % " PRIu64 , 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        tx ,  idx ,  pstate - > inspect_id [ direction ] ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                if  ( pstate - > inspect_id [ direction ] + 1  = =  idx ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                    pstate - > inspect_id [ direction ]  =  idx ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            if  ( ! ires . has_next ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                break ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
			
			 
			 
			
				@ -808,31 +879,38 @@ void AppLayerParserTransactionsCleanup(Flow *f)
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    const  int  tx_end_state_ts  =  AppLayerParserGetStateProgressCompletionStatus ( alproto ,  STREAM_TOSERVER ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    const  int  tx_end_state_tc  =  AppLayerParserGetStateProgressCompletionStatus ( alproto ,  STREAM_TOCLIENT ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    SCLogDebug ( " checking % " PRIu64 "  txs from offset % " PRIu64 ,  total_txs ,  min ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    for  ( uint64_t  i  =  min  ;  i  <  total_txs ;  i + + )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        void  *  const  tx  =  AppLayerParserGetTx ( ipproto ,  alproto ,  alstate ,  i ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        if  ( tx  = =  NULL )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            SCLogDebug ( " %p/% " PRIu64 "  skipping: no tx " ,  tx ,  i ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            goto  wrap_up ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    AppLayerGetTxIteratorFunc  IterFunc  =  AppLayerGetTxIterator ( ipproto ,  alproto ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    AppLayerGetTxIterState  state ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    memset ( & state ,  0 ,  sizeof ( state ) ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    uint64_t  i  =  min ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    uint64_t  new_min  =  min ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    while  ( 1 )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        AppLayerGetTxIterTuple  ires  =  IterFunc ( ipproto ,  alproto ,  alstate ,  i ,  total_txs ,  & state ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        if  ( ires . tx_ptr  = =  NULL ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            break ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        void  * tx  =  ires . tx_ptr ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        i  =  ires . tx_id ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        SCLogDebug ( " %p/% " PRIu64 "  checking " ,  tx ,  i ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        const  int  tx_progress_tc  =  AppLayerParserGetStateProgress ( ipproto ,  alproto ,  tx ,  STREAM_TOCLIENT ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        if  ( tx_progress_tc  <  tx_end_state_tc )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            SCLogDebug ( " %p/% " PRIu64 "  skipping: tc parser not done " ,  tx ,  i ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            continue ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            goto next  ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        const  int  tx_progress_ts  =  AppLayerParserGetStateProgress ( ipproto ,  alproto ,  tx ,  STREAM_TOSERVER ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        if  ( tx_progress_ts  <  tx_end_state_ts )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            SCLogDebug ( " %p/% " PRIu64 "  skipping: ts parser not done " ,  tx ,  i ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            continue ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            goto next  ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        if  ( f - > sgh_toserver  ! =  NULL )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            uint64_t  detect_flags_ts  =  AppLayerParserGetTxDetectFlags ( ipproto ,  alproto ,  tx ,  STREAM_TOSERVER ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            if  ( ! ( detect_flags_ts  &  APP_LAYER_TX_INSPECTED_FLAG ) )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                SCLogDebug ( " %p/% " PRIu64 "  skipping: TS inspect not done: ts:% " PRIx64 , 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        tx ,  i ,  detect_flags_ts ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                continue ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                goto next  ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        if  ( f - > sgh_toclient  ! =  NULL )  { 
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -840,7 +918,7 @@ void AppLayerParserTransactionsCleanup(Flow *f)
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            if  ( ! ( detect_flags_tc  &  APP_LAYER_TX_INSPECTED_FLAG ) )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                SCLogDebug ( " %p/% " PRIu64 "  skipping: TC inspect not done: tc:% " PRIx64 , 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        tx ,  i ,  detect_flags_tc ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                continue ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                goto next  ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        if  ( logger_expectation  ! =  0 )  { 
 
			
		 
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
			
			 
			 
			
				@ -848,25 +926,32 @@ void AppLayerParserTransactionsCleanup(Flow *f)
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            if  ( tx_logged  ! =  logger_expectation )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                SCLogDebug ( " %p/% " PRIu64 "  skipping: logging not done: want:% " PRIx32 " , have:% " PRIx32 , 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                        tx ,  i ,  logger_expectation ,  tx_logged ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                continue ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                goto next  ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        /* if we are here, the tx can be freed. */ 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        p - > StateTransactionFree ( alstate ,  i ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        SCLogDebug ( " %p/% " PRIu64 "  freed " ,  tx ,  i ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    wrap_up : 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        /* see if this tx is actually in order. If so, we need to bring all
 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				         *  trackers  up  to  date .  */ 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        SCLogDebug ( " %p/% " PRIu64 "  update f->alparser->min_id? % " PRIu64 ,  tx ,  i ,  alparser - > min_id ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        if  ( i  = =  alparser - > min_id )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            uint64_t  next_id  =  i  +  1 ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            alparser - > min_id  =  next_id ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            alparser - > inspect_id [ 0 ]  =  MAX ( alparser - > inspect_id [ 0 ] ,  next_id ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            alparser - > inspect_id [ 1 ]  =  MAX ( alparser - > inspect_id [ 1 ] ,  next_id ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            alparser - > log_id  =  MAX ( alparser - > log_id ,  next_id ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            SCLogDebug ( " %p/% " PRIu64 "  updated f->alparser->min_id % " PRIu64 ,  tx ,  i ,  alparser - > min_id ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        /* if this tx was the minimum, up the minimum */ 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        if  ( i  = =  new_min ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            new_min  =  i  +  1 ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				next : 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        if  ( ! ires . has_next ) 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            break ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    /* see if we need to bring all trackers up to date. */ 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    SCLogDebug ( " update f->alparser->min_id? % " PRIu64 ,  alparser - > min_id ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    if  ( new_min  >  alparser - > min_id )  { 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        const  uint64_t  next_id  =  new_min ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        alparser - > min_id  =  next_id ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        alparser - > inspect_id [ 0 ]  =  MAX ( alparser - > inspect_id [ 0 ] ,  next_id ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        alparser - > inspect_id [ 1 ]  =  MAX ( alparser - > inspect_id [ 1 ] ,  next_id ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        alparser - > log_id  =  MAX ( alparser - > log_id ,  next_id ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        SCLogDebug ( " updated f->alparser->min_id % " PRIu64 ,  alparser - > min_id ) ; 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    } 
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				}