diff --git a/elements/userlevel/fromdevice.cc b/elements/userlevel/fromdevice.cc index 212fafe257..132c4ce8ca 100644 --- a/elements/userlevel/fromdevice.cc +++ b/elements/userlevel/fromdevice.cc @@ -44,6 +44,7 @@ #include #include #include "fakepcap.hh" +#include #if FROMDEVICE_ALLOW_LINUX # include diff --git a/elements/userlevel/khandlerproxy.cc b/elements/userlevel/khandlerproxy.cc index 86208c07fd..1a372af5ba 100644 --- a/elements/userlevel/khandlerproxy.cc +++ b/elements/userlevel/khandlerproxy.cc @@ -26,6 +26,7 @@ #include #include #include +#include #include CLICK_DECLS diff --git a/elements/userlevel/rawsocket.cc b/elements/userlevel/rawsocket.cc index 40e9ce25eb..1e4fb25f36 100644 --- a/elements/userlevel/rawsocket.cc +++ b/elements/userlevel/rawsocket.cc @@ -34,6 +34,7 @@ #include #include #include +#include #ifndef __sun #include diff --git a/elements/userlevel/socket.cc b/elements/userlevel/socket.cc index 83e38f2c86..4148267321 100644 --- a/elements/userlevel/socket.cc +++ b/elements/userlevel/socket.cc @@ -31,6 +31,8 @@ #include #include #include +#include +#include #include "socket.hh" #ifdef HAVE_PROPER @@ -40,12 +42,12 @@ CLICK_DECLS Socket::Socket() - : _task(this), + : _task(this), _timer(this), _fd(-1), _active(-1), _rq(0), _wq(0), _local_port(0), _local_pathname(""), _timestamp(true), _sndbuf(-1), _rcvbuf(-1), _snaplen(2048), _headroom(Packet::default_headroom), _nodelay(1), - _verbose(false), _client(false), _proper(false), _allow(0), _deny(0) + _verbose(false), _client(false), _proper(false), _allow(0), _deny(0), _reconnect_call_h(0) { } @@ -53,6 +55,19 @@ Socket::~Socket() { } +void Socket::run_timer(Timer *) { + + ErrorHandler *errh = new ErrorHandler(); + + if (_active == -1) { + initialize(errh); + } + + _timer.reschedule_after_sec(2); + return; + +} + int Socket::configure(Vector &conf, ErrorHandler *errh) { @@ -63,6 +78,7 @@ Socket::configure(Vector &conf, ErrorHandler *errh) return -1; socktype = socktype.upper(); + String reconnect_call; // remove keyword arguments Element *allow = 0, *deny = 0; if (args.read("VERBOSE", _verbose) @@ -74,11 +90,15 @@ Socket::configure(Vector &conf, ErrorHandler *errh) .read("NODELAY", _nodelay) .read("CLIENT", _client) .read("PROPER", _proper) + .read("RECONNECT_CALL", AnyArg(), reconnect_call) .read("ALLOW", allow) .read("DENY", deny) .consume() < 0) return -1; + if (reconnect_call) + _reconnect_call_h = new HandlerCall(reconnect_call); + if (allow && !(_allow = (IPRouteTable *)allow->cast("IPRouteTable"))) return errh->error("%s is not an IPRouteTable", allow->name().c_str()); @@ -134,12 +154,24 @@ Socket::initialize_socket_error(ErrorHandler *errh, const char *syscall) _fd = -1; } - return errh->error("%s: %s", syscall, strerror(e)); + click_chatter("%s: %s: %s", declaration().c_str(), syscall, strerror(e)); + + return 0; + } int Socket::initialize(ErrorHandler *errh) { + + // initialize timer + _timer.initialize(this); + _timer.reschedule_after_sec(2); + + // initialize callback + if (_reconnect_call_h && (_reconnect_call_h->initialize_write(this, errh) < 0)) + return initialize_socket_error(errh, "callback"); + // open socket, set options _fd = socket(_family, _socktype, _protocol); if (_fd < 0) @@ -250,6 +282,9 @@ Socket::initialize(ErrorHandler *errh) add_select(_fd, SELECT_WRITE); } + if (_reconnect_call_h) + (void) _reconnect_call_h->call_write(); + return 0; } diff --git a/elements/userlevel/socket.hh b/elements/userlevel/socket.hh index 7fdd5d68aa..6c7a8e7844 100644 --- a/elements/userlevel/socket.hh +++ b/elements/userlevel/socket.hh @@ -4,9 +4,11 @@ #include #include #include +#include #include #include "../ip/iproutetable.hh" #include +#include CLICK_DECLS /* @@ -186,6 +188,7 @@ class Socket : public Element { public: void add_handlers() CLICK_COLD; bool run_task(Task *); + void run_timer(Timer *); void selected(int fd, int mask); void push(int port, Packet*); @@ -195,6 +198,7 @@ class Socket : public Element { public: protected: Task _task; + Timer _timer; private: int _fd; // socket descriptor @@ -237,6 +241,8 @@ private: int initialize_socket_error(ErrorHandler *, const char *); + HandlerCall *_reconnect_call_h; + }; CLICK_ENDDECLS