Source: ../../fea/win_rtm_pipe.hh
|
|
|
|
// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
// vim:set sts=4 ts=8:
// Copyright (c) 2001-2007 International Computer Science Institute
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software")
// to deal in the Software without restriction, subject to the conditions
// listed in the XORP LICENSE file. These conditions include: you must
// preserve this copyright notice, and you cannot mention the copyright
// holders in advertising related to the Software without their permission.
// The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
// notice is a summary of the XORP LICENSE file; the license in that file is
// legally binding.
// $XORP: xorp/fea/win_rtm_pipe.hh,v 1.3 2007/02/16 22:45:51 pavlin Exp $
#ifndef __FEA_WIN_RTM_PIPE_HH__
#define __FEA_WIN_RTM_PIPE_HH__
#include <list>
#include "libxorp/eventloop.hh"
#include "libxorp/exceptions.hh"
class WinRtmPipeObserver;
struct WinRtmPipePlumber;
/**
* WinRtmPipe class opens a routing socket and forwards data arriving
* on the socket to WinRtmPipeObservers. The WinRtmPipe hooks itself
* into the EventLoop and activity usually happens asynchronously.
*/
class WinRtmPipe {
public:
WinRtmPipe(EventLoop& eventloop);
~WinRtmPipe();
/**
* Start the routing socket operation for a given address family.
*
* @param af the address family.
* @param error_msg the error message (if error).
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
int start(int af, string& error_msg);
/**
* Stop the routing socket operation.
*
* @param error_msg the error message (if error).
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
int stop(string& error_msg);
/**
* Test if the routing socket is open.
*
* This method is needed because WinRtmPipe may fail to open
* routing socket during startup.
*
* @return true if the routing socket is open, otherwise false.
*/
inline bool is_open() const { return _fd.is_valid(); }
/**
* Write data to routing socket.
*
* This method also updates the sequence number associated with
* this routing socket.
*
* @return the number of bytes which were written, or -1 if error.
*/
ssize_t write(const void* data, size_t nbytes);
/**
* Get the sequence number for next message written into the kernel.
*
* The sequence number is derived from the instance number of this routing
* socket and a 16-bit counter.
*
* @return the sequence number for the next message written into the
* kernel.
*/
inline uint32_t seqno() const { return (_instance_no << 16 | _seqno); }
/**
* Get the cached process identifier value.
*
* @return the cached process identifier value.
*/
inline pid_t pid() const { return _pid; }
/**
* Force socket to read data.
*
* This usually is performed after writing a request that the
* kernel will answer (e.g., after writing a route lookup).
* Use sparingly, with caution, and at your own risk.
*
* @param error_msg the error message (if error).
* @return XORP_OK on success, otherwise XORP_ERROR.
*/
int force_read(string& error_msg);
private:
typedef list<WinRtmPipeObserver*> ObserverList;
/**
* Read data available for WinRtmPipe and invoke
* WinRtmPipeObserver::rtsock_data() on all observers of routing
* socket.
*/
void io_event(XorpFd fd, IoEventType type);
WinRtmPipe& operator=(const WinRtmPipe&); // Not implemented
WinRtmPipe(const WinRtmPipe&); // Not implemented
private:
static const size_t RTSOCK_BYTES = 8*1024; // Initial guess at msg size
private:
EventLoop& _eventloop;
XorpFd _fd;
ObserverList _ol;
uint16_t _seqno; // Seqno of next write()
uint16_t _instance_no; // Instance number of this routing socket
static uint16_t _instance_cnt;
static pid_t _pid;
friend class WinRtmPipePlumber; // class that hooks observers in and out
};
class WinRtmPipeObserver {
public:
WinRtmPipeObserver(WinRtmPipe& rs);
virtual ~WinRtmPipeObserver();
/**
* Receive data from the routing socket.
*
* Note that this method is called asynchronously when the routing socket
* has data to receive, therefore it should never be called directly by
* anything else except the routing socket facility itself.
*
* @param buffer the buffer with the received data.
*/
virtual void rtsock_data(const vector<uint8_t>& buffer) = 0;
/**
* Get WinRtmPipe associated with Observer.
*/
WinRtmPipe& routing_socket();
private:
WinRtmPipe& _rs;
};
#endif // __FEA_WIN_RTM_PIPE_HH__
Generated by: pavlin on possum.icir.org on Wed Mar 21 11:23:22 2007, using kdoc $.