mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00

Some uninitialized values, a possible null pointer dereference, and time-of-check-time-of-use on reading random seed file.
164 lines
4.5 KiB
C++
164 lines
4.5 KiB
C++
// Implements persistance for Bro's data structures.
|
|
|
|
#ifndef persistence_serializer_h
|
|
#define persistence_serializer_h
|
|
|
|
#include "Serializer.h"
|
|
#include "List.h"
|
|
|
|
class StateAccess;
|
|
|
|
class PersistenceSerializer : public FileSerializer {
|
|
public:
|
|
PersistenceSerializer();
|
|
virtual ~PersistenceSerializer();
|
|
|
|
// Define the directory where to store the data.
|
|
void SetDir(const char* arg_dir) { dir = copy_string(arg_dir); }
|
|
|
|
// Register/unregister the ID/connection to be saved by WriteAll().
|
|
void Register(ID* id);
|
|
void Unregister(ID* id);
|
|
void Register(Connection* conn);
|
|
void Unregister(Connection* conn);
|
|
|
|
// Read all data that has been changed since last scan of directory.
|
|
// is_init should be true for the first read upon start-up. All existing
|
|
// state will be cleared. If delete_files is true, file which have been
|
|
// read are removed (even if the read was unsuccessful!).
|
|
bool ReadAll(bool is_init, bool delete_files);
|
|
|
|
// Each of the following four methods may suspend operation.
|
|
// If they do, they install a Timer which resumes after some
|
|
// amount of time. If a function is called again before it
|
|
// has completely finished its task, it will do nothing and
|
|
// return false.
|
|
|
|
bool WriteState(bool may_suspend);
|
|
|
|
// Writes Bro's configuration (w/o dynamic state).
|
|
bool WriteConfig(bool may_suspend);
|
|
|
|
// Sends all registered state to remote host
|
|
// (by leveraging the remote_serializer).
|
|
bool SendState(SourceID peer, bool may_suspend);
|
|
|
|
// Sends Bro's config to remote host
|
|
// (by leveraging the remote_serializer).
|
|
bool SendConfig(SourceID peer, bool may_suspend);
|
|
|
|
// Returns true if a serialization is currently running.
|
|
bool IsSerializationRunning() const { return running.length(); }
|
|
|
|
// Tells the serializer that this access was performed. If a
|
|
// serialization is going on, it may store it. (Need only be called if
|
|
// IsSerializationRunning() returns true.)
|
|
bool LogAccess(const StateAccess& s);
|
|
|
|
protected:
|
|
friend class RemoteSerializer;
|
|
friend class IncrementalWriteTimer;
|
|
|
|
virtual void GotID(ID* id, Val* val);
|
|
virtual void GotEvent(const char* name, double time,
|
|
EventHandlerPtr event, val_list* args);
|
|
virtual void GotFunctionCall(const char* name, double time,
|
|
Func* func, val_list* args) ;
|
|
virtual void GotStateAccess(StateAccess* s);
|
|
virtual void GotTimer(Timer* t);
|
|
virtual void GotConnection(Connection* c);
|
|
virtual void GotPacket(Packet* packet);
|
|
|
|
// If file has changed since last check, read it.
|
|
bool CheckForFile(UnserialInfo* info, const char* file,
|
|
bool delete_file);
|
|
|
|
// Returns true if it's a regular file and has a more recent timestamp
|
|
// than last time we checked it.
|
|
bool CheckTimestamp(const char* file);
|
|
|
|
// Move file from <dir>/tmp/<file> to <dir>/<file>. Afterwards, call
|
|
// CheckTimestamp() with <dir>/<file>.
|
|
bool MoveFileUp(const char* dir, const char* file);
|
|
|
|
// Generates an error message, terminates current serialization,
|
|
// and returns false.
|
|
bool SerialError(const char* msg);
|
|
|
|
// Start a new serialization.
|
|
struct SerialStatus;
|
|
bool RunSerialization(SerialStatus* status);
|
|
|
|
// Helpers for RunSerialization.
|
|
bool DoIDSerialization(SerialStatus* status, ID* id);
|
|
bool DoConnSerialization(SerialStatus* status, Connection* conn);
|
|
bool DoAccessSerialization(SerialStatus* status, StateAccess* access);
|
|
|
|
typedef PDict(ID) id_map;
|
|
|
|
declare(PDict, Connection);
|
|
typedef PDict(Connection) conn_map;
|
|
|
|
struct SerialStatus {
|
|
enum Type {
|
|
WritingState, WritingConfig,
|
|
SendingState, SendingConfig,
|
|
};
|
|
|
|
SerialStatus(Serializer* s, Type arg_type) : info(s)
|
|
{
|
|
type = arg_type;
|
|
ids = 0;
|
|
id_cookie = 0;
|
|
conns = 0;
|
|
conn_cookie = 0;
|
|
peer = SOURCE_LOCAL;
|
|
filename = 0;
|
|
}
|
|
|
|
Type type;
|
|
SerialInfo info;
|
|
|
|
// IDs to serialize.
|
|
id_map* ids;
|
|
IterCookie* id_cookie;
|
|
|
|
// Connections to serialize.
|
|
conn_map* conns;
|
|
IterCookie* conn_cookie;
|
|
|
|
// Accesses performed while we're serializing.
|
|
declare(PList,StateAccess);
|
|
typedef PList(StateAccess) state_access_list;
|
|
state_access_list accesses;
|
|
|
|
// The ID/Conn we're currently serializing.
|
|
union {
|
|
ID* id;
|
|
Connection* conn;
|
|
} current;
|
|
|
|
// Only set if type is Writing{State,Config}.
|
|
const char* filename;
|
|
|
|
// Only set if type is Sending{State,Config}.
|
|
SourceID peer;
|
|
};
|
|
|
|
const char* dir;
|
|
|
|
declare(PList, SerialStatus);
|
|
PList(SerialStatus) running;
|
|
|
|
id_map persistent_ids;
|
|
conn_map persistent_conns;
|
|
|
|
// To keep track of files' modification times.
|
|
declare(PDict, time_t);
|
|
typedef PDict(time_t) file_map;
|
|
file_map files;
|
|
};
|
|
|
|
extern PersistenceSerializer* persistence_serializer;
|
|
|
|
#endif
|