📄 umlswitch.cc
字号:
// -*- mode: c++; c-basic-offset: 2 -*-/* * umlswitch.{cc,hh} -- connects to uml_switch * * Mark Huang <mlhuang@cs.princeton.edu> * Copyright (C) 2005 The Trustees of Princeton University * * $Id: umlswitch.cc,v 1.1 2006/06/21 21:07:45 eddietwo Exp $ */#include <click/config.h>#include <click/error.hh>#include <click/confparse.hh>#include <click/straccum.hh>#include <unistd.h>#include <sys/socket.h>#include <sys/un.h>#include "umlswitch.hh"CLICK_DECLSintUMLSwitch::configure(Vector<String> &conf, ErrorHandler *errh){ if (cp_va_kparse(conf, this, errh, "PATH", cpkP, cpFilename, &_ctl_path, cpEnd) < 0) return -1; return 0;}intUMLSwitch::initialize(ErrorHandler *errh){ int err = 0, addrlen; Vector<String> socket_conf; // connect to uml_switch control socket _control = socket(AF_UNIX, SOCK_STREAM, 0); if (_control < 0) { err = errh->error("could not create control socket"); goto done; } _ctl_addr.sun_family = AF_UNIX; if (_ctl_path.length() >= (int)sizeof(((struct sockaddr_un *)0)->sun_path)) { err = errh->error("path to uml_switch control socket too long"); goto done; } strcpy(_ctl_addr.sun_path, _ctl_path.c_str()); addrlen = offsetof(struct sockaddr_un, sun_path) + _ctl_path.length() + 1; if (connect(_control, (struct sockaddr *)&_ctl_addr, addrlen) < 0) { err = errh->error("could not connect to control socket %s: %s", _ctl_path.c_str(), strerror(errno)); goto done; } // set up a local address struct { char zero; int pid; int usecs; } name; name.zero = 0; name.pid = getpid(); name.usecs = Timestamp::now().usec(); _local_addr.sun_family = AF_UNIX; memcpy(_local_addr.sun_path, &name, sizeof(name)); // tell uml_switch our local address struct request_v3 req; req.magic = SWITCH_MAGIC; req.version = SWITCH_VERSION; req.type = REQ_NEW_CONTROL; req.sock = _local_addr; if (write(_control, &req, sizeof(req)) != sizeof(req)) { err = errh->error("control setup request failed: %s", strerror(errno)); goto done; } // get remote address from uml_switch if (read(_control, &_data_addr, sizeof(_data_addr)) != sizeof(_data_addr)) { err = errh->error("read of data socket failed: %s", strerror(errno)); goto done; } // configure and initialize Socket parameters addrlen = (int)sizeof(((struct sockaddr_un *)0)->sun_path); socket_conf.push_back(String("UNIX_DGRAM")); socket_conf.push_back(String('"') + String::make_stable(_data_addr.sun_path, addrlen).quoted_hex() + String('"')); socket_conf.push_back(String('"') + String::make_stable(_local_addr.sun_path, addrlen).quoted_hex() + String('"')); socket_conf.push_back(String("CLIENT true")); if ((err = Socket::configure(socket_conf, errh)) || (err = Socket::initialize(errh))) goto done; done: return err;}voidUMLSwitch::cleanup(CleanupStage stage){ Socket::cleanup(stage); if (_control >= 0) close(_control);}CLICK_ENDDECLSELEMENT_REQUIRES(Socket)EXPORT_ELEMENT(UMLSwitch)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -