// $Id: SteppingStone.h,v 1.12 2003/08/31 00:38:11 vern Exp $
//
// Copyright (c) 1999, 2002
//      The Regents of the University of California.  All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that: (1) source code distributions
// retain the above copyright notice and this paragraph in its entirety, (2)
// distributions including binary code include the above copyright notice and
// this paragraph in its entirety in the documentation or other materials
// provided with the distribution, and (3) all advertising materials mentioning
// features or use of this software display the following acknowledgement:
// ``This product includes software developed by the University of California,
// Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
// the University nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

#ifndef steppingstone_h
#define steppingstone_h

#include "Queue.h"
#include "TCP.h"

class NetSessions;

class SteppingStoneEndpoint;
class SteppingStoneManager;

declare(PQueue,SteppingStoneEndpoint);
declare(PDict,SteppingStoneEndpoint);

class SteppingStoneEndpoint : public TCP_EndpointAnalyzer {
public:
	SteppingStoneEndpoint(TCP_Endpoint* e, SteppingStoneManager* m);
	~SteppingStoneEndpoint();
	void Done();

	int DataSent(double t, int seq, int len, const u_char* data,
		     const IP_Hdr* ip, const struct tcphdr* tp);

protected:
	void Event(EventHandlerPtr f, int id1, int id2 = -1);
	void CreateEndpEvent(int is_orig);

	int stp_max_top_seq;
	double stp_last_time;
	double stp_resume_time;
	SteppingStoneManager* stp_manager;

	// Hashes for inbound/outbound endpoints that are correlated
	// at least once with this endpoint.  They are necessary for
	// removing correlated endpoint pairs in Bro, since there is
	// no LOOP in Bro language.
	int stp_id;
	HashKey* stp_key;
	PDict(SteppingStoneEndpoint) stp_inbound_endps;
	PDict(SteppingStoneEndpoint) stp_outbound_endps;
};

class SteppingStoneAnalyzer : public TCP_Analyzer {
public:
	SteppingStoneAnalyzer(TCP_Connection* c, SteppingStoneManager* m);
	void Done();

protected:
	SteppingStoneManager* stp_manager;
	SteppingStoneEndpoint* orig_endp;
	SteppingStoneEndpoint* resp_endp;
};

// Manages ids for the possible stepping stone connections.
class SteppingStoneManager {
public:
	SteppingStoneManager()		{ endp_cnt = 0; }

	PQueue(SteppingStoneEndpoint)& OrderedEndpoints()
		{ return ordered_endps; }

	// Use postfix ++, since the first ID needs to be even.
	int NextID()			{ return endp_cnt++; }

protected:
	PQueue(SteppingStoneEndpoint) ordered_endps;
	int endp_cnt;
};

#endif /* steppingstone_h */
