📄 controlsocket.hh
字号:
#ifndef CLICK_CONTROLSOCKET_HH#define CLICK_CONTROLSOCKET_HH#include "elements/userlevel/handlerproxy.hh"CLICK_DECLSclass ControlSocketErrorHandler;class Timer;class Handler;/*=cControlSocket("TCP", PORTNUMBER [, I<KEYWORDS>])ControlSocket("UNIX", FILENAME [, I<KEYWORDS>])=s debuggingopens control sockets for other programs=ioNone=dOpens a control socket that allows other user-level programs to call read orwrite handlers on the router. Depending on its configuration string,ControlSocket will listen on TCP port PORTNUMBER, or on a UNIX-domain socketnamed FILENAME. With the PROXY keyword argument, you can make ControlSocket speak toa kernel driver; see below.The "server" (that is, the ControlSocket element) speaks a relativelysimple line-based protocol. Commands sent to the server are single lines oftext; they consist of words separated by spaces. The server responds toevery command with at least one message line followed optionally by somedata. Message lines start with a three-digit response code, as in FTP. Whenmultiple message lines are sent in response to a single command, all butthe last begin with the response code and a hyphen (as in "200-Hello!");the last line begins with the response code and a space (as in "200Hello!").The server will accept lines terminated by CR, LF, or CRLF. Its responselines are always terminated by CRLF.When a connection is opened, the server responds by stating its protocolversion number with a line like "Click::ControlSocket/1.1". The currentversion number is 1.1. Changes in minor version number will only add commandsand functionality to this specification, not change existing functionality.ControlSocket supports hot-swapping, meaning you can change configurationswithout interrupting existing clients. The hot-swap will succeed only if theold ControlSocket and the new ControlSocket have the same element name, andthe same socket type and port/filename parameters. Additionally, the newControlSocket must have RETRIES set to 1 or more, since the old ControlSockethas already bound the relevant socket.Keyword arguments are:=over 8=item READONLYBoolean. Disallows write handlers if true (it is false bydefault). =item PROXYString. Specifies an element proxy. When a user requests the value of handlerE.H, ControlSocket will actually return the value of `PROXY.E.H'. This isuseful with elements like KernelHandlerProxy. Default is empty (no proxy).=item VERBOSEBoolean. When true, ControlSocket will print messages whenever it accepts anew connection or drops an old one. Default is false.=item RETRIESInteger. If greater than 0, ControlSocket won't immediately fail when it can'topen its socket. Instead, it will attempt to open the socket once a seconduntil it succeeds, or until RETRIES unsuccessful attempts (after which it willstop the router). Default is 0.=item RETRY_WARNINGSBoolean. If true, ControlSocket will print warning messages every time itfails to open a socket. If false, it will print messages only on the finalfailure. Default is true.=back=head1 SERVER COMMANDSThe server currently supports the following six commands. Many of the commandstake a I<handler> argument. These arguments name handlers, and take one ofthree forms: C<I<elementname>.I<handlername>> names a particular element'shandler; C<I<elementnumber>.I<handlername>> also names an element handler, butthe element is identified by index, starting from 1; and C<I<handlername>>names a global handler. (There are seven global read handlers, namedC<version>, C<list>, C<classes>, C<config>, C<flatconfig>, C<packages>, andC<requirements>. See click.o(8) for more information.)=over 5=item READ I<handler> [I<params...>]Call a read I<handler>, passing the I<params>, if any,as arguments, and return the results.On success, responds with a "success" message (responsecode 2xy) followed by a line like "DATA I<n>". Here, I<n> is adecimal integer indicating the length of the read handler data. The I<n>bytes immediately following (the CRLF that terminates) the DATA line arethe handler's results.=item WRITE I<handler> I<params...>Call a write I<handler>, passing the I<params>, if any, as arguments.=item WRITEDATA I<handler> I<n>Call a write I<handler>. The arguments to pass are the I<n> bytes immediatelyfollowing (the CRLF that terminates) the WRITEDATA line.=item CHECKREAD I<handler>Checks whether a I<handler> exists and is readable. The return status is 200for readable handlers, and an appropriate error status for non-readablehandlers or nonexistent handlers.=item CHECKWRITE I<handler>Checks whether a I<handler> exists and is writable.=item LLRPC I<llrpc> [I<n>]Call an LLRPC I<llrpc> and return the results. I<Llrpc> should have the formC<I<element>#I<hexnumber>>. The C<I<hexnumber>> is the LLRPC number, fromC<E<lt>click/llrpc.hE<gt>>, in hexadecimal network format. Translate C<CLICK_LLRPC>constants to network format by callingC<CLICK_LLRPC_HTON(CLICK_LLRPC_...)>. If I<n> is given, then the I<n> bytesimmediately following (the CRLF that terminates) the LLRPC line are passed inas an argument. The results are returned after a "DATA I<nn>" line, as inREAD.ControlSocket will not call an LLRPC unless it can determine (from the commandnumber) how much data the LLRPC expects and returns. (Only "flat" LLRPCs maybe called; they are declared using the _CLICK_IOC_[RWS]F macros.)=item QUITClose the connection.=backThe server's response codes follow this pattern.=over 5=item 2xyThe command succeeded.=item 5xyThe command failed.=backHere are some of the particular error messages: 200 OK. 220 OK, but the handler reported some warnings. 500 Syntax error. 501 Unimplemented command. 510 No such element. 511 No such handler. 520 Handler error. 530 Permission denied. 540 No router installed.ControlSocket is only available in user-level processes.=e ControlSocket(unix, /tmp/clicksocket);=a ChatterSocket, KernelHandlerProxy */class ControlSocket : public Element { public: ControlSocket(); ~ControlSocket(); const char *class_name() const { return "ControlSocket"; } int configure(Vector<String> &conf, ErrorHandler *); int initialize(ErrorHandler *); void cleanup(CleanupStage); void take_state(Element *, ErrorHandler *); void selected(int); enum { CSERR_OK = HandlerProxy::CSERR_OK, // 200 CSERR_OK_HANDLER_WARNING = 220, CSERR_SYNTAX = HandlerProxy::CSERR_SYNTAX, // 500 CSERR_UNIMPLEMENTED = 501, CSERR_NO_SUCH_ELEMENT = HandlerProxy::CSERR_NO_SUCH_ELEMENT, // 510 CSERR_NO_SUCH_HANDLER = HandlerProxy::CSERR_NO_SUCH_HANDLER, // 511 CSERR_HANDLER_ERROR = HandlerProxy::CSERR_HANDLER_ERROR, // 520 CSERR_DATA_TOO_BIG = 521, CSERR_LLRPC_ERROR = 522, CSERR_PERMISSION = HandlerProxy::CSERR_PERMISSION, // 530 CSERR_NO_ROUTER = HandlerProxy::CSERR_NO_ROUTER, // 540 CSERR_UNSPECIFIED = HandlerProxy::CSERR_UNSPECIFIED // 590 }; private: String _unix_pathname; int _socket_fd; bool _read_only : 1; bool _verbose : 1; bool _retry_warnings : 1; bool _tcp_socket : 1; Element *_proxy; HandlerProxy *_full_proxy; Vector<String> _in_texts; Vector<String> _out_texts; Vector<int> _flags; String _proxied_handler; ErrorHandler *_proxied_errh; int _retries; Timer *_retry_timer; enum { READ_CLOSED = 1, WRITE_CLOSED = 2, ANY_ERR = -1 }; static const char protocol_version[]; int initialize_socket_error(ErrorHandler *, const char *); int initialize_socket(ErrorHandler *); static void retry_hook(Timer *, void *); int message(int fd, int code, const String &, bool continuation = false); int transfer_messages(int fd, int default_code, const String &first_message, ControlSocketErrorHandler *); String proxied_handler_name(const String &) const; const Handler* parse_handler(int fd, const String &, Element **); int read_command(int fd, const String &, const String &); int write_command(int fd, const String &, const String &); int check_command(int fd, const String &, bool write); int llrpc_command(int fd, const String &, String); int parse_command(int fd, const String &); void flush_write(int fd, bool read_needs_processing); int report_proxy_errors(int fd, const String &); static ErrorHandler *proxy_error_function(const String &, void *);};CLICK_ENDDECLS#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -