⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 csclient.hh

📁 Click is a modular router toolkit. To use it you ll need to know how to compile and install the sof
💻 HH
字号:
/* * csclient.{cc,hh} -- class for connecting to Click ControlSockets. * Douglas S. J. De Couto <decouto@lcs.mit.edu> * based on the author's ControlSocket.java which was improved by Eddie Kohler */#include <string>#include <vector>#include <assert.h>#include <unistd.h>/* * NB: obscure implementation note: this class does not handle EINTR * errors from any of the read/write calls.  If this is relevant to * your program, this class may not do the ``right thing'' */class ControlSocketClient{public:  ControlSocketClient() : _init(false), _fd(0) { }  ControlSocketClient(ControlSocketClient &) : _init(false), _fd(0) { }  enum err_t {    no_err = 0,    sys_err,            /* O/S or networking error, check errno for more information */    init_err,           /* tried to perform operation on an unconfigured ControlSocketClient */    reinit_err,         /* tried to re-configure the client before close()ing it */    no_element,         /* specified element does not exist */    no_handler,         /* specified handler does not exist */    handler_no_perm,    /* router denied access to the specified handler */    handler_err,        /* handler returned an error */    handler_bad_format, /* bad format in calling handler */    click_err,          /* unexpected response or error from the router */    too_short           /* user buffer was too short */  };  /*   * Configure a new ControlSocketClient.   * HOST_IP is IP address (in network byte order) of the machine that user-level click is running on   * PORT is the IP port the ControlSocket is listening on.   * Returns: no_err, sys_err, reinit_err, click_err   * If returns no_err, the client is properly configured; otherwise the client is unconfigured.   */  err_t configure(unsigned int host_ip, unsigned short port);  /*   * Close a configured client.   * Returns: no_err, sys_err, init_err   * In any case, the client is left unconfigured.   */  err_t close();  /*   * Return a string describing the ControlSocket's host and port.   * Requires: object is configured   */  const string name() { assert(_init); return _name; }  /*   * NB: the following functions return data about or send data to the   * click router via the ControlSocket.  Unless otherwise noted, the   * data returned or sent is undefined unless the function's return   * value is no_err.   */  /*   * Get a string containing the router's configuration   * (get_router_config) or flattened configuration   * (get_router_flat_config).   * CONFIG is filled with the configuration; existing contents are replaced.   * Returns: no_err, no_handler, handler_err, handler_no_perm, sys_err, init_err, click_err   */  err_t get_router_config(string &config)         { return read("", "config", config); }  err_t get_router_flat_config(string &config)    { return read("", "flatconfig", config); }  /*   * Get a string containing the router's version   * VERS is filled with the version; existing contents are replaced.   * Returns: no_err, no_handler, handler_err, handler_no_perm, sys_err, init_err, click_err   */  err_t get_router_version(string &vers)  { err_t err = read("", "version", vers); vers = trim(vers); return err; }  /*   * Get the names of the elements in the the current router configuration.   * ELS is filled with the names, existing contents are replaced.   * Returns: no_err, no_handler, handler_err, handler_no_perm, sys_err, init_err, click_err   */  err_t get_config_el_names(vector<string> &els);  /*   * Get the names of the element types that the router knows about.   * CLASSES is filled with the names, existing contents are replaced.   * Returns: no_err, no_handler, handler_err, handler_no_perm, sys_err, init_err, click_err   */  err_t get_router_classes(vector<string> &classes)   { return get_string_vec("", "classes", classes); }  /*   * Get the names of the packages that the router knows about.   * PACKAGES is filled with the names, existing contents are replaced.   * Returns: no_err, no_handler, handler_err, handler_no_perm, sys_err, init_err, click_err   */  err_t get_router_packages(vector<string> &pkgs)  { return get_string_vec("", "packages", pkgs); }  /*   * Get the names of the current router configuration requirements.   * REQS is filled with the names, existing contents are replaced.   * Returns: no_err, no_handler, handler_err, handler_no_perm, sys_err, init_err, click_err   */  err_t get_config_reqs(vector<string> &reqs)         { return get_string_vec("", "requirements", reqs); }  struct handler_info_t {    string element_name;    string handler_name;    bool can_read;    bool can_write;    handler_info_t() : can_read(false), can_write(false) { }  };  /*   * Get the information about an element's handlers in the current router configuration.   * EL is the element's name.   * HANDLERS is filled with the handler info, existing contents are replaced.   * Returns: no_err, no_element, handler_err, handler_no_perm, sys_err, init_err, click_err   */  err_t get_el_handlers(string el, vector<handler_info_t> &handlers);  /*   * Check whether a read/write handler exists.   * EL is the element's name.   * H is the handler's name.   * IS_WRITE true to check for write handler, otherwise check read handler.   * EXISTS is filled with true if the handler exists, otherwise false.   * Returns: no_err, sys_err, init_err, click_err   */  err_t check_handler(string el, string h, bool is_write, bool &exists);protected:  err_t check_handler_workaround(string el, string h, bool is_write, bool &exists);public:  /*   * Return the results of reading a handler.   * EL is the element's name.   * HANDLER is the handler name.   * RESPONSE is filled with the handler's output, existing contents are replaced.   * If NAME is not empty, calls``NAME.HANDLER''; otherwise calls ``HANDLER''   * Returns: no_err, no_element, no_handler, handler_err, handler_no_perm, sys_err, init_err, click_err   */  err_t read(string el, string handler, string &response);  /*   * Return the results of reading a handler.   * EL is the element's name.   * HANDLER is the handler name.   * BUF receives the data.   * BUFSZ is the size of BUF, and recieves the actual number of characters placed into BUF.   * If NAME is not empty, calls``NAME.HANDLER''; otherwise calls ``HANDLER''   * Returns: no_err, no_element, no_handler, handler_err, handler_no_perm, sys_err, init_err, click_err, too_short   * If returns too_short, the operation succeeded, but returned more than BUFSZ characters; the first BUFSZ   * characters of the result are placed into BUF, and BUFSZ is unchanged.   */  err_t read(string el, string handler, char *buf, int &bufsz);  /*   * Write data to an element's handler.   * EL is the element's name.   * HANDLER is the handler name.   * DATA contains the data.  No terminating '\0' is written.   * If NAME is not empty, calls``NAME.HANDLER''; otherwise calls ``HANDLER''   * Returns: no_err, no_element, no_handler, handler_err, handler_no_perm, sys_err, init_err, click_err   */  err_t write(string el, string handler, string data);  /*   * Write data to an element's handler.   * EL is the element's name.   * HANDLER is the handler name.   * BUF contains the data.   * BUFSZ is the number of characters to be written from BUF.   * If NAME is not empty, calls``NAME.HANDLER''; otherwise calls ``HANDLER''   * Returns: no_err, no_element, no_handler, handler_err, handler_no_perm, sys_err, init_err, click_err   */  err_t write(string el, string handler, const char *buf, int bufsz);  /*   * sugar, for reading and writing handlers.   */  err_t read(handler_info_t h, string &response)      { return read(h.element_name, h.handler_name, response); }  err_t read(handler_info_t h, char *buf, int &bufsz) { return read(h.element_name, h.handler_name, buf, bufsz); }  err_t write(handler_info_t h, string data)          { return write(h.element_name, h.handler_name, data); }  err_t write(handler_info_t h, const char *buf, int bufsz) { return write(h.element_name, h.handler_name, buf, bufsz); }  ~ControlSocketClient() { if (_init) ::close(_fd); }private:  bool _init;  unsigned int _host;  unsigned short _port;  int _fd;  int _protocol_minor_version;  string _name;  enum {    CODE_OK = 200,    CODE_OK_WARN = 220,    CODE_SYNTAX_ERR = 500,    CODE_UNIMPLEMENTED = 501,    CODE_NO_ELEMENT = 510,    CODE_NO_HANDLER = 511,    CODE_HANDLER_ERR = 520,    CODE_PERMISSION = 530,    CODE_NO_ROUTER = 540,    PROTOCOL_MAJOR_VERSION = 1,    PROTOCOL_MINOR_VERSION = 0  };  /* Try to read a '\n'-terminated line (including the '\n') from the   * socket.  */  err_t readline(string &buf);  int get_resp_code(string line);  int get_data_len(string line);  err_t handle_err_code(int code);  err_t get_string_vec(string el, string h, vector<string> &v);  vector<string> split(string s, size_t offset, char terminator);  string trim(string s);};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -