PageRenderTime 52ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/elements/userlevel/socket.cc

https://github.com/bhesmans/click
C++ | 543 lines | 416 code | 68 blank | 59 comment | 170 complexity | 036a4a8dbb62817a30c4b2da7d889e62 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause
  1. // -*- mode: c++; c-basic-offset: 2 -*-
  2. /*
  3. * socket.{cc,hh} -- transports packets via sockets
  4. * Mark Huang <mlhuang@cs.princeton.edu>
  5. *
  6. * Copyright (c) 2004 The Trustees of Princeton University (Trustees).
  7. * Copyright (c) 2006-2007 Regents of the University of California
  8. *
  9. * Permission is hereby granted, free of charge, to any person obtaining a
  10. * copy of this software and associated documentation files (the "Software"),
  11. * to deal in the Software without restriction, subject to the conditions
  12. * listed in the Click LICENSE file. These conditions include: you must
  13. * preserve this copyright notice, and you cannot mention the copyright
  14. * holders in advertising related to the Software without their permission.
  15. * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
  16. * notice is a summary of the Click LICENSE file; the license in that file is
  17. * legally binding.
  18. */
  19. #include <click/config.h>
  20. #include <click/error.hh>
  21. #include <click/args.hh>
  22. #include <click/glue.hh>
  23. #include <click/standard/scheduleinfo.hh>
  24. #include <click/packet_anno.hh>
  25. #include <click/packet.hh>
  26. #include <unistd.h>
  27. #include <sys/ioctl.h>
  28. #include <sys/socket.h>
  29. #include <sys/un.h>
  30. #include <arpa/inet.h>
  31. #include <netinet/tcp.h>
  32. #include <fcntl.h>
  33. #include "socket.hh"
  34. #ifdef HAVE_PROPER
  35. #include <proper/prop.h>
  36. #endif
  37. CLICK_DECLS
  38. Socket::Socket()
  39. : _task(this), _timer(this),
  40. _fd(-1), _active(-1), _rq(0), _wq(0),
  41. _local_port(0), _local_pathname(""),
  42. _timestamp(true), _sndbuf(-1), _rcvbuf(-1),
  43. _snaplen(2048), _headroom(Packet::default_headroom), _nodelay(1),
  44. _verbose(false), _client(false), _proper(false), _allow(0), _deny(0)
  45. {
  46. }
  47. Socket::~Socket()
  48. {
  49. }
  50. int
  51. Socket::configure(Vector<String> &conf, ErrorHandler *errh)
  52. {
  53. String socktype;
  54. _client = (noutputs() == 0);
  55. Args args = Args(this, errh).bind(conf);
  56. if (args.read_mp("TYPE", socktype).execute() < 0)
  57. return -1;
  58. socktype = socktype.upper();
  59. // remove keyword arguments
  60. Element *allow = 0, *deny = 0;
  61. if (args.read("VERBOSE", _verbose)
  62. .read("SNAPLEN", _snaplen)
  63. .read("HEADROOM", _headroom)
  64. .read("TIMESTAMP", _timestamp)
  65. .read("RCVBUF", _rcvbuf)
  66. .read("SNDBUF", _sndbuf)
  67. .read("NODELAY", _nodelay)
  68. .read("CLIENT", _client)
  69. .read("PROPER", _proper)
  70. .read("ALLOW", allow)
  71. .read("DENY", deny)
  72. .consume() < 0)
  73. return -1;
  74. if (allow && !(_allow = (IPRouteTable *)allow->cast("IPRouteTable")))
  75. return errh->error("%s is not an IPRouteTable", allow->name().c_str());
  76. if (deny && !(_deny = (IPRouteTable *)deny->cast("IPRouteTable")))
  77. return errh->error("%s is not an IPRouteTable", deny->name().c_str());
  78. if (socktype == "TCP" || socktype == "UDP") {
  79. _family = AF_INET;
  80. _socktype = socktype == "TCP" ? SOCK_STREAM : SOCK_DGRAM;
  81. _protocol = socktype == "TCP" ? IPPROTO_TCP : IPPROTO_UDP;
  82. if (args.read_mp("ADDR", _remote_ip)
  83. .read_mp("PORT", IPPortArg(_protocol), _remote_port)
  84. .read_p("LOCAL_ADDR", _local_ip)
  85. .read_p("LOCAL_PORT", IPPortArg(_protocol), _local_port)
  86. .complete() < 0)
  87. return -1;
  88. }
  89. else if (socktype == "UNIX" || socktype == "UNIX_DGRAM") {
  90. _family = AF_UNIX;
  91. _socktype = socktype == "UNIX" ? SOCK_STREAM : SOCK_DGRAM;
  92. _protocol = 0;
  93. if (args.read_mp("FILENAME", FilenameArg(), _remote_pathname)
  94. .read_p("LOCAL_FILENAME", FilenameArg(), _local_pathname)
  95. .complete() < 0)
  96. return -1;
  97. int max_path = (int)sizeof(((struct sockaddr_un *)0)->sun_path);
  98. // if not in the abstract namespace (begins with zero byte),
  99. // reserve room for trailing NUL
  100. if ((_remote_pathname[0] && _remote_pathname.length() >= max_path) ||
  101. (_remote_pathname[0] == 0 && _remote_pathname.length() > max_path))
  102. return errh->error("remote filename '%s' too long", _remote_pathname.printable().c_str());
  103. if ((_local_pathname[0] && _local_pathname.length() >= max_path) ||
  104. (_local_pathname[0] == 0 && _local_pathname.length() > max_path))
  105. return errh->error("local filename '%s' too long", _local_pathname.printable().c_str());
  106. }
  107. else
  108. return errh->error("unknown socket type `%s'", socktype.c_str());
  109. return 0;
  110. }
  111. int
  112. Socket::initialize_socket_error(ErrorHandler *errh, const char *syscall)
  113. {
  114. int e = errno; // preserve errno
  115. if (_fd >= 0) {
  116. remove_select(_fd, SELECT_READ | SELECT_WRITE);
  117. close(_fd);
  118. _fd = -1;
  119. }
  120. return errh->error("%s: %s", syscall, strerror(e));
  121. }
  122. int
  123. Socket::initialize(ErrorHandler *errh)
  124. {
  125. // open socket, set options
  126. _fd = socket(_family, _socktype, _protocol);
  127. if (_fd < 0)
  128. return initialize_socket_error(errh, "socket");
  129. if (_family == AF_INET) {
  130. _remote.in.sin_family = _family;
  131. _remote.in.sin_port = htons(_remote_port);
  132. _remote.in.sin_addr = _remote_ip.in_addr();
  133. _remote_len = sizeof(_remote.in);
  134. _local.in.sin_family = _family;
  135. _local.in.sin_port = htons(_local_port);
  136. _local.in.sin_addr = _local_ip.in_addr();
  137. _local_len = sizeof(_local.in);
  138. }
  139. else {
  140. _remote.un.sun_family = _family;
  141. _remote_len = offsetof(struct sockaddr_un, sun_path) + _remote_pathname.length();
  142. if (_remote_pathname[0]) {
  143. strcpy(_remote.un.sun_path, _remote_pathname.c_str());
  144. _remote_len++;
  145. } else
  146. memcpy(_remote.un.sun_path, _remote_pathname.c_str(), _remote_pathname.length());
  147. _local.un.sun_family = _family;
  148. _local_len = offsetof(struct sockaddr_un, sun_path) + _local_pathname.length();
  149. if (_local_pathname[0]) {
  150. strcpy(_local.un.sun_path, _local_pathname.c_str());
  151. _local_len++;
  152. } else
  153. memcpy(_local.un.sun_path, _local_pathname.c_str(), _local_pathname.length());
  154. }
  155. // enable timestamps
  156. if (_timestamp) {
  157. #ifdef SO_TIMESTAMP
  158. int one = 1;
  159. if (setsockopt(_fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one)) < 0)
  160. return initialize_socket_error(errh, "setsockopt(SO_TIMESTAMP)");
  161. #else
  162. return initialize_socket_error(errh, "TIMESTAMP not supported on this platform");
  163. #endif
  164. }
  165. #ifdef TCP_NODELAY
  166. // disable Nagle algorithm
  167. if (_protocol == IPPROTO_TCP && _nodelay)
  168. if (setsockopt(_fd, IP_PROTO_TCP, TCP_NODELAY, &_nodelay, sizeof(_nodelay)) < 0)
  169. return initialize_socket_error(errh, "setsockopt(TCP_NODELAY)");
  170. #endif
  171. // set socket send buffer size
  172. if (_sndbuf >= 0)
  173. if (setsockopt(_fd, SOL_SOCKET, SO_SNDBUF, &_sndbuf, sizeof(_sndbuf)) < 0)
  174. return initialize_socket_error(errh, "setsockopt(SO_SNDBUF)");
  175. // set socket receive buffer size
  176. if (_rcvbuf >= 0)
  177. if (setsockopt(_fd, SOL_SOCKET, SO_RCVBUF, &_rcvbuf, sizeof(_rcvbuf)) < 0)
  178. return initialize_socket_error(errh, "setsockopt(SO_RCVBUF)");
  179. // if a server, then the first arguments should be interpreted as
  180. // the address/port/file to bind() to, not to connect() to
  181. if (!_client) {
  182. memcpy(&_local, &_remote, _remote_len);
  183. _local_len = _remote_len;
  184. }
  185. // if a server, or if the optional local arguments have been
  186. // specified, bind() to the specified address/port/file
  187. if (!_client || _local_port != 0 || _local_pathname != "") {
  188. #ifdef HAVE_PROPER
  189. int ret = -1;
  190. if (_proper) {
  191. ret = prop_bind_socket(_fd, (struct sockaddr *)&_local, _local_len);
  192. if (ret < 0)
  193. errh->warning("prop_bind_socket: %s", strerror(errno));
  194. }
  195. if (ret < 0)
  196. #endif
  197. if (bind(_fd, (struct sockaddr *)&_local, _local_len) < 0)
  198. return initialize_socket_error(errh, "bind");
  199. }
  200. if (_client) {
  201. // connect
  202. if (_socktype == SOCK_STREAM) {
  203. if (connect(_fd, (struct sockaddr *)&_remote, _remote_len) < 0)
  204. return initialize_socket_error(errh, "connect");
  205. if (_verbose)
  206. click_chatter("%s: opened connection %d to %s:%d", declaration().c_str(), _fd, IPAddress(_remote.in.sin_addr).unparse().c_str(), ntohs(_remote.in.sin_port));
  207. }
  208. _active = _fd;
  209. } else {
  210. // start listening
  211. if (_socktype == SOCK_STREAM) {
  212. if (listen(_fd, 2) < 0)
  213. return initialize_socket_error(errh, "listen");
  214. if (_verbose) {
  215. if (_family == AF_INET)
  216. click_chatter("%s: listening for connections on %s:%d (%d)", declaration().c_str(), IPAddress(_local.in.sin_addr).unparse().c_str(), ntohs(_local.in.sin_port), _fd);
  217. else
  218. click_chatter("%s: listening for connections on %s (%d)", declaration().c_str(), _local.un.sun_path, _fd);
  219. }
  220. } else {
  221. _active = _fd;
  222. }
  223. }
  224. // nonblocking I/O and close-on-exec for the socket
  225. fcntl(_fd, F_SETFL, O_NONBLOCK);
  226. fcntl(_fd, F_SETFD, FD_CLOEXEC);
  227. if (noutputs())
  228. add_select(_fd, SELECT_READ);
  229. if (ninputs() && input_is_pull(0)) {
  230. ScheduleInfo::join_scheduler(this, &_task, errh);
  231. _signal = Notifier::upstream_empty_signal(this, 0, &_task);
  232. add_select(_fd, SELECT_WRITE);
  233. _timer.initialize(this);
  234. }
  235. return 0;
  236. }
  237. void
  238. Socket::cleanup(CleanupStage)
  239. {
  240. if (_active >= 0 && _active != _fd) {
  241. close(_active);
  242. _active = -1;
  243. }
  244. if (_rq)
  245. _rq->kill();
  246. if (_wq)
  247. _wq->kill();
  248. if (_fd >= 0) {
  249. // shut down the listening socket in case we forked
  250. #ifdef SHUT_RDWR
  251. shutdown(_fd, SHUT_RDWR);
  252. #else
  253. shutdown(_fd, 2);
  254. #endif
  255. close(_fd);
  256. if (_family == AF_UNIX)
  257. unlink(_local_pathname.c_str());
  258. _fd = -1;
  259. }
  260. }
  261. bool
  262. Socket::allowed(IPAddress addr)
  263. {
  264. IPAddress gw;
  265. if (_allow && _allow->lookup_route(addr, gw) >= 0)
  266. return true;
  267. else if (_deny && _deny->lookup_route(addr, gw) >= 0)
  268. return false;
  269. else
  270. return true;
  271. }
  272. void
  273. Socket::close_active(void)
  274. {
  275. if (_active >= 0) {
  276. remove_select(_active, SELECT_READ | SELECT_WRITE);
  277. close(_active);
  278. if (_verbose)
  279. click_chatter("%s: closed connection %d", declaration().c_str(), _active);
  280. _active = -1;
  281. }
  282. }
  283. void
  284. Socket::selected(int fd, int)
  285. {
  286. int len;
  287. union { struct sockaddr_in in; struct sockaddr_un un; } from;
  288. socklen_t from_len = sizeof(from);
  289. bool allow;
  290. if (noutputs()) {
  291. // accept new connections
  292. if (_socktype == SOCK_STREAM && !_client && _active < 0 && fd == _fd) {
  293. _active = accept(_fd, (struct sockaddr *)&from, &from_len);
  294. if (_active < 0) {
  295. if (errno != EAGAIN)
  296. click_chatter("%s: accept: %s", declaration().c_str(), strerror(errno));
  297. return;
  298. }
  299. if (_family == AF_INET) {
  300. allow = allowed(IPAddress(from.in.sin_addr));
  301. if (_verbose)
  302. click_chatter("%s: %s connection %d from %s:%d", declaration().c_str(),
  303. allow ? "opened" : "denied",
  304. _active, IPAddress(from.in.sin_addr).unparse().c_str(), ntohs(from.in.sin_port));
  305. if (!allow) {
  306. close(_active);
  307. _active = -1;
  308. return;
  309. }
  310. } else {
  311. if (_verbose)
  312. click_chatter("%s: opened connection %d from %s", declaration().c_str(), _active, from.un.sun_path);
  313. }
  314. fcntl(_active, F_SETFL, O_NONBLOCK);
  315. fcntl(_active, F_SETFD, FD_CLOEXEC);
  316. add_select(_active, SELECT_READ | SELECT_WRITE);
  317. _events = SELECT_READ | SELECT_WRITE;
  318. }
  319. // read data from socket
  320. if (!_rq)
  321. _rq = Packet::make(_headroom, 0, _snaplen, 0);
  322. if (_rq) {
  323. if (_socktype == SOCK_STREAM)
  324. len = read(_active, _rq->data(), _rq->length());
  325. else if (_client)
  326. len = recv(_active, _rq->data(), _rq->length(), MSG_TRUNC);
  327. else {
  328. // datagram server, find out who we are talking to
  329. len = recvfrom(_active, _rq->data(), _rq->length(), MSG_TRUNC, (struct sockaddr *)&from, &from_len);
  330. if (_family == AF_INET && !allowed(IPAddress(from.in.sin_addr))) {
  331. if (_verbose)
  332. click_chatter("%s: dropped datagram from %s:%d", declaration().c_str(),
  333. IPAddress(from.in.sin_addr).unparse().c_str(), ntohs(from.in.sin_port));
  334. len = -1;
  335. errno = EAGAIN;
  336. } else if (len > 0) {
  337. memcpy(&_remote, &from, from_len);
  338. _remote_len = from_len;
  339. }
  340. }
  341. // this segment OK
  342. if (len > 0) {
  343. if (len > _snaplen) {
  344. // truncate packet to max length (should never happen)
  345. assert(_rq->length() == (uint32_t)_snaplen);
  346. SET_EXTRA_LENGTH_ANNO(_rq, len - _snaplen);
  347. } else {
  348. // trim packet to actual length
  349. _rq->take(_snaplen - len);
  350. }
  351. // set timestamp
  352. if (_timestamp)
  353. _rq->timestamp_anno().assign_now();
  354. // push packet
  355. output(0).push(_rq);
  356. _rq = 0;
  357. }
  358. // connection terminated or fatal error
  359. else if (len == 0 || errno != EAGAIN) {
  360. if (errno != EAGAIN && _verbose)
  361. click_chatter("%s: %s", declaration().c_str(), strerror(errno));
  362. close_active();
  363. return;
  364. }
  365. }
  366. }
  367. if (ninputs() && input_is_pull(0))
  368. run_task(0);
  369. }
  370. int
  371. Socket::write_packet(Packet *p)
  372. {
  373. int len;
  374. assert(_active >= 0);
  375. while (p->length()) {
  376. if (!IPAddress(_remote_ip) && _client && _family == AF_INET && _socktype != SOCK_STREAM) {
  377. // If the IP address specified when the element was created is 0.0.0.0,
  378. // send the packet to its IP destination annotation address
  379. _remote.in.sin_addr = p->dst_ip_anno();
  380. }
  381. // write segment
  382. if (_socktype == SOCK_STREAM)
  383. len = write(_active, p->data(), p->length());
  384. else
  385. len = sendto(_active, p->data(), p->length(), 0,
  386. (struct sockaddr *)&_remote, _remote_len);
  387. // error
  388. if (len < 0) {
  389. // out of memory or would block
  390. if (errno == ENOBUFS || errno == EAGAIN)
  391. return -1;
  392. // interrupted by signal, try again immediately
  393. else if (errno == EINTR)
  394. continue;
  395. // connection probably terminated or other fatal error
  396. else {
  397. if (_verbose)
  398. click_chatter("%s: %s", declaration().c_str(), strerror(errno));
  399. close_active();
  400. break;
  401. }
  402. } else
  403. // this segment OK
  404. p->pull(len);
  405. }
  406. p->kill();
  407. return 0;
  408. }
  409. void
  410. Socket::push(int, Packet *p)
  411. {
  412. fd_set fds;
  413. int err;
  414. if (_active >= 0) {
  415. // block
  416. do {
  417. FD_ZERO(&fds);
  418. FD_SET(_active, &fds);
  419. err = select(_active + 1, NULL, &fds, NULL, NULL);
  420. } while (err < 0 && errno == EINTR);
  421. if (err >= 0) {
  422. // write
  423. do {
  424. err = write_packet(p);
  425. } while (err < 0 && (errno == ENOBUFS || errno == EAGAIN));
  426. }
  427. if (err < 0) {
  428. if (_verbose)
  429. click_chatter("%s: %s, dropping packet", declaration().c_str(), strerror(err));
  430. p->kill();
  431. }
  432. } else
  433. p->kill();
  434. }
  435. bool
  436. Socket::run_task(Task *)
  437. {
  438. assert(ninputs() && input_is_pull(0));
  439. bool any = false;
  440. if (_active >= 0) {
  441. Packet *p = 0;
  442. int err = 0;
  443. // write as much as we can
  444. do {
  445. p = _wq ? _wq : input(0).pull();
  446. _wq = 0;
  447. if (p) {
  448. any = true;
  449. err = write_packet(p);
  450. }
  451. } while (p && err >= 0);
  452. if (err < 0) {
  453. // queue packet for writing when socket becomes available
  454. _wq = p;
  455. p = 0;
  456. add_select(_active, SELECT_WRITE);
  457. } else if (_signal)
  458. // more pending
  459. // (can't use fast_reschedule() cause selected() calls this)
  460. _task.reschedule();
  461. else
  462. // wrote all we could and no more pending
  463. remove_select(_active, SELECT_WRITE);
  464. }
  465. // true if we wrote at least one packet
  466. return any;
  467. }
  468. void
  469. Socket::add_handlers()
  470. {
  471. add_task_handlers(&_task);
  472. }
  473. CLICK_ENDDECLS
  474. ELEMENT_REQUIRES(userlevel IPRouteTable)
  475. EXPORT_ELEMENT(Socket)