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

/src/socket.cc

https://bitbucket.org/modelnine/protoproxy
C++ | 794 lines | 466 code | 70 blank | 258 comment | 114 complexity | e53b9b138b1d46b1b393797683fa747d MD5 | raw file
  1. /*
  2. * socket.cc
  3. *
  4. * Copyright (c) 2012, Heiko Wundram.
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are met:
  9. *
  10. * * Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * * Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * * Neither the name of modelnine.org, protoproxy nor the names of its
  16. * contributors may be used to endorse or promote products derived from
  17. * this software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  20. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22. * ARE DISCLAIMED. IN NO EVENT SHALL HEIKO WUNDRAM BE LIABLE FOR ANY
  23. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  25. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  26. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  28. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. *
  30. * Created on: 31.01.2012
  31. * Author: Heiko Wundram <modelnine@modelnine.org>
  32. */
  33. #include <sys/socket.h>
  34. #include <sys/types.h>
  35. #include <cassert>
  36. #include <cerrno>
  37. #include <cstdarg>
  38. #include <cstddef>
  39. #include <ctime>
  40. #include <fcntl.h>
  41. #include <poll.h>
  42. #include <unistd.h>
  43. #include "exceptions.hh"
  44. #include "logger.hh"
  45. #include "reactor.hh"
  46. #include "socket.hh"
  47. #include "types.hh"
  48. using namespace protoproxy;
  49. using namespace std;
  50. /**
  51. * Handle attachment of socket to reactor.
  52. */
  53. void socket::handle_attach() {
  54. // Default does nothing.
  55. debug("Default attach action called on socket attach for socket at %p",
  56. static_cast<void*>(this));
  57. }
  58. /**
  59. * Handle error on socket.
  60. */
  61. void socket::handle_error() {
  62. // Check type of socket to handle error response.
  63. if( m_destroy ) {
  64. // Socket can be destroyed, do so on unhandled error.
  65. warning("Default socket error callback called on socket at %p,"
  66. " destroying destructible socket",
  67. static_cast<void*>(this));
  68. delete this;
  69. } else {
  70. // Just detach the socket on error callback, can't be destroyed.
  71. warning("Default socket error callback called on socket at %p,"
  72. " detaching non-destructible socket",
  73. static_cast<void*>(this));
  74. detach();
  75. }
  76. }
  77. /**
  78. * Handle read condition on socket.
  79. */
  80. void socket::handle_read() {
  81. // Throw exception.
  82. error("Default read callback called with socket event for socket at %p",
  83. static_cast<void*>(this));
  84. throw not_implemented_error("Read event called, but not implemented");
  85. }
  86. #if POLLRDBAND != POLLPRI
  87. /**
  88. * Handle priority read condition on socket.
  89. */
  90. void socket::handle_priority_read() {
  91. // Throw exception.
  92. error("Default priority read callback called with socket event for socket"
  93. " at %p", static_cast<void*>(this));
  94. throw not_implemented_error("Priority read event called, but not"
  95. " implemented");
  96. }
  97. #endif
  98. /**
  99. * Handle high priority read condition on socket.
  100. */
  101. void socket::handle_high_priority_read() {
  102. // Throw exception.
  103. error("Default high priority read callback called with socket event for"
  104. " socket at %p", static_cast<void*>(this));
  105. throw not_implemented_error("High priority read event called, but not"
  106. " implemented");
  107. }
  108. /**
  109. * Handle write condition on socket.
  110. */
  111. void socket::handle_write() {
  112. // Throw exception.
  113. error("Default write callback called with socket event for socket at %p",
  114. static_cast<void*>(this));
  115. throw not_implemented_error("Write event called, but not implemented");
  116. }
  117. #if POLLWRBAND != POLLWRNORM
  118. /**
  119. * Handle priority write condition on socket.
  120. */
  121. void socket::handle_priority_write() {
  122. // Throw exception.
  123. error("Default priority write callback called with socket event for socket"
  124. " at %p", static_cast<void*>(this));
  125. throw not_implemented_error("Priority write event called, but not"
  126. " implemented");
  127. }
  128. #endif
  129. /**
  130. * Handle hangup on socket, signalling that the socket is done.
  131. */
  132. void socket::handle_hangup() {
  133. // Default implementation does nothing on hangup.
  134. info("Default socket hangup callback called for socket at %p, doing"
  135. " nothing", static_cast<void*>(this));
  136. }
  137. /**
  138. * Handle timeout condition on socket timeout, dispatching the timeout id.
  139. */
  140. void socket::handle_timeout(const size_t id __attribute__((unused))) {
  141. // Throw exception.
  142. error("Default socket timeout callback called with no event attached for"
  143. " socket at %p", static_cast<void*>(this));
  144. throw not_implemented_error("Timeout event called, but not implemented");
  145. }
  146. /**
  147. * Handle detachment of the socket from a reactor.
  148. */
  149. void socket::handle_detach() {
  150. // Default does nothing.
  151. debug("Default socket detach callback called on socket detach for socket"
  152. " at %p", static_cast<void*>(this));
  153. }
  154. /**
  155. * Handle log message to socket with the specified arguments.
  156. */
  157. void socket::log(const loglevel level, const logdomain domain,
  158. const char* const msg, va_list args) {
  159. // Check for reactor, if so, dispatch it there.
  160. assert(msg);
  161. if( m_reactor )
  162. // Dispatch log message to reactor, reusing arguments.
  163. m_reactor->log(level, domain, msg, args);
  164. else {
  165. // TODO: need to think of something to do here.
  166. }
  167. }
  168. /**
  169. * Initialize a new socket which is not bound to a reactor or a file
  170. * descriptor.
  171. */
  172. socket::socket(const bool destroy, const logdomain defdomain) :
  173. logger(defdomain), m_destroy(destroy), m_reactor(0), m_prev(),
  174. m_next(), m_fd(-1), m_events(), m_nexttimeoutid(0), m_nexttimeout(0),
  175. m_lasttimeout() {
  176. // No specific construction.
  177. debug("New socket at %p, no bound socket", static_cast<void*>(this));
  178. }
  179. /**
  180. * Create a new socket of the specified socket type.
  181. */
  182. socket::socket(const int domain, const int type, const int protocol,
  183. const bool destroy, const logdomain defdomain) :
  184. logger(defdomain), m_destroy(destroy), m_reactor(0), m_prev(),
  185. m_next(), m_fd(), m_events(0), m_nexttimeoutid(0), m_nexttimeout(0),
  186. m_lasttimeout() {
  187. // Initialize descriptor.
  188. debug("New socket at %p, creating socket domain %i, type %i, protocol %i",
  189. static_cast<void*>(this), domain, type, protocol);
  190. if( ( m_fd = ::socket(domain, type, protocol) ) == -1 )
  191. throw os_error("Failed to initialize new socket of specified type");
  192. try {
  193. // Try to set new socket to non-blocking.
  194. int flags;
  195. if( ( flags = fcntl(m_fd, F_GETFL) ) == -1 )
  196. throw os_error("Failed to get socket flags");
  197. else if( fcntl(m_fd, F_SETFL, flags | O_NONBLOCK) == -1 )
  198. throw os_error("Failed to set socket to non-blocking");
  199. } catch( ... ) {
  200. // Clean up socket on error exit.
  201. ::close(m_fd);
  202. throw;
  203. }
  204. }
  205. /**
  206. * Initialize socket bound to existing file descriptor.
  207. */
  208. socket::socket(const int fd, const bool destroy, const logdomain defdomain) :
  209. logger(defdomain), m_destroy(destroy), m_reactor(0), m_prev(),
  210. m_next(), m_fd(fd), m_events(0), m_nexttimeoutid(0), m_nexttimeout(0),
  211. m_lasttimeout() {
  212. // Try to set socket to non-blocking; we don't close on error.
  213. debug("New socket at %p, using existing descriptor %i",
  214. static_cast<void*>(this), fd);
  215. assert(m_fd>=0);
  216. int flags;
  217. if( ( flags = fcntl(m_fd, F_GETFL) ) == -1 )
  218. throw os_error("Failed to get socket flags");
  219. else if( fcntl(m_fd, F_SETFL, flags | O_NONBLOCK) == -1 )
  220. throw os_error("Failed to set socket to non-blocking");
  221. }
  222. /**
  223. * Access reference to currently bound reactor.
  224. */
  225. reactor& socket::reactor_() const {
  226. // Return reactor.
  227. if( !m_reactor )
  228. throw state_error("Trying to access reactor when not set up");
  229. return *m_reactor;
  230. }
  231. /**
  232. * Set up event mask for socket to enable reads.
  233. */
  234. void socket::want_read(const bool read) {
  235. // Set up flag depending on boolean.
  236. if( m_fd < 0 )
  237. throw state_error("Trying to set up events on closed socket");
  238. else if( read ) {
  239. // Set the flag in event mask.
  240. debug("Setting read flag on socket event mask for socket at %p",
  241. static_cast<void*>(this));
  242. m_events |= POLLRDNORM;
  243. } else {
  244. // Clear the flag in event mask.
  245. debug("Clearing read flag on socket event mask for socket at %p",
  246. static_cast<void*>(this));
  247. m_events &= ~POLLRDNORM;
  248. }
  249. // Dispatch events to descriptor if appropriate.
  250. if( m_reactor ) {
  251. // Set up event flags in reactor polling descriptor.
  252. assert(m_reactor->m_pollfds&&
  253. static_cast<size_t>(m_fd)<m_reactor->m_pollfdsize&&
  254. m_reactor->m_pollfds[m_fd].fd>=0&&
  255. (m_reactor->m_pollfds[m_fd].events&~POLLRDNORM)==(m_events&~POLLRDNORM));
  256. m_reactor->m_pollfds[m_fd].events = m_events;
  257. }
  258. }
  259. #if POLLRDBAND != POLLPRI
  260. /**
  261. * Set up event mask for socket to enable priority reads.
  262. */
  263. void socket::want_priority_read(const bool read) {
  264. // Set up flag depending on boolean.
  265. if( m_fd < 0 )
  266. throw state_error("Trying to set up events on closed socket");
  267. else if( read ) {
  268. // Set the flag in event mask.
  269. debug("Setting priority read flag on socket event mask for socket at"
  270. " %p", static_cast<void*>(this));
  271. m_events |= POLLRDBAND;
  272. } else {
  273. // Clear the flag in event mask.
  274. debug("Clearing priority read flag on socket event mask for socket at"
  275. " %p", static_cast<void*>(this));
  276. m_events &= ~POLLRDBAND;
  277. }
  278. // Dispatch events to descriptor if appropriate.
  279. if( m_reactor ) {
  280. // Set up event flags in reactor polling descriptor.
  281. assert(m_reactor->m_pollfds&&
  282. static_cast<size_t>(m_fd)<m_reactor->m_pollfdsize&&
  283. m_reactor->m_pollfds[m_fd].fd>=0&&
  284. (m_reactor->m_pollfds[m_fd].events&~POLLRDBAND)==(m_events&~POLLRDBAND));
  285. m_reactor->m_pollfds[m_fd].events = m_events;
  286. }
  287. }
  288. #endif
  289. /**
  290. * Set up event mask for socket to enable high priority reads.
  291. */
  292. void socket::want_high_priority_read(const bool read) {
  293. // Set up flag depending on boolean.
  294. if( m_fd < 0 )
  295. throw state_error("Trying to set up events on closed socket");
  296. else if( read ) {
  297. // Set the flag in event mask.
  298. debug("Setting high priority read flag on socket event mask for"
  299. " socket at %p", static_cast<void*>(this));
  300. m_events |= POLLPRI;
  301. } else {
  302. // Clear the flag in event mask.
  303. debug("Clearing high priority read flag on socket event mask for"
  304. " socket at %p", static_cast<void*>(this));
  305. m_events &= ~POLLPRI;
  306. }
  307. // Dispatch events to descriptor if appropriate.
  308. if( m_reactor ) {
  309. // Set up event flags in reactor polling descriptor.
  310. assert(m_reactor->m_pollfds&&
  311. static_cast<size_t>(m_fd)<m_reactor->m_pollfdsize&&
  312. m_reactor->m_pollfds[m_fd].fd>=0&&
  313. (m_reactor->m_pollfds[m_fd].events&~POLLPRI)==(m_events&~POLLPRI));
  314. m_reactor->m_pollfds[m_fd].events = m_events;
  315. }
  316. }
  317. /**
  318. * Set up event mask for socket to enable writes.
  319. */
  320. void socket::want_write(const bool write) {
  321. // Set up flag depending on boolean.
  322. if( m_fd < 0 )
  323. throw state_error("Trying to set up events on closed socket");
  324. else if( write ) {
  325. // Set the flag in event mask.
  326. debug("Setting write flag on socket event mask for socket at %p",
  327. static_cast<void*>(this));
  328. m_events |= POLLWRNORM;
  329. } else {
  330. // Clear the flag in event mask.
  331. debug("Clearing write flag on socket event mask for socket at %p",
  332. static_cast<void*>(this));
  333. m_events &= ~POLLWRNORM;
  334. }
  335. // Dispatch events to descriptor if appropriate.
  336. if( m_reactor ) {
  337. // Set up event flags in reactor polling descriptor.
  338. assert(m_reactor->m_pollfds&&
  339. static_cast<size_t>(m_fd)<m_reactor->m_pollfdsize&&
  340. m_reactor->m_pollfds[m_fd].fd>=0&&
  341. (m_reactor->m_pollfds[m_fd].events&~POLLWRNORM)==(m_events&~POLLWRNORM));
  342. m_reactor->m_pollfds[m_fd].events = m_events;
  343. }
  344. }
  345. #if POLLWRBAND != POLLWRNORM
  346. /**
  347. * Set up event mask for socket to enable priority writes.
  348. */
  349. void socket::want_priority_write(const bool write) {
  350. // Set up flag depending on boolean.
  351. if( m_fd < 0 )
  352. throw state_error("Trying to set up events on closed socket");
  353. else if( write ) {
  354. // Set the flag in event mask.
  355. debug("Setting priority write flag on socket event mask for socket at"
  356. " %p", static_cast<void*>(this));
  357. m_events |= POLLWRBAND;
  358. } else {
  359. // Clear the flag in event mask.
  360. debug("Clearing priority write flag on socket event mask for socket at"
  361. " %p", static_cast<void*>(this));
  362. m_events &= ~POLLWRBAND;
  363. }
  364. // Dispatch events to descriptor if appropriate.
  365. if( m_reactor ) {
  366. // Set up event flags in reactor polling descriptor.
  367. assert(m_reactor->m_pollfds&&
  368. static_cast<size_t>(m_fd)<m_reactor->m_pollfdsize&&
  369. m_reactor->m_pollfds[m_fd].fd>=0&&
  370. (m_reactor->m_pollfds[m_fd].events&~POLLWRBAND)==(m_events&~POLLWRBAND));
  371. m_reactor->m_pollfds[m_fd].events = m_events;
  372. }
  373. }
  374. #endif
  375. /**
  376. * Attach a new timeout callback to this socket, which fires after the
  377. * specified time.
  378. */
  379. size_t socket::addtimeout(const int msecs) {
  380. // Fetch new timeout object.
  381. assert(!m_nexttimeout||m_lasttimeout);
  382. socket_timeout* newtimeout;
  383. if( m_reactor && m_reactor->m_freetimeouts ) {
  384. // Fetch object from reactor and update new element.
  385. debug("Attaching new timeout %i on socket %p, reusing timeout object",
  386. msecs, static_cast<void*>(this));
  387. newtimeout = m_reactor->m_freetimeouts;
  388. m_reactor->m_freetimeouts = newtimeout->m_next;
  389. } else {
  390. // Need to allocate new timeout object; if we fail here, raise as is.
  391. debug("Attaching new timeout %i on socket %p, creating timeout object",
  392. msecs, static_cast<void*>(this));
  393. newtimeout = new socket_timeout();
  394. }
  395. try {
  396. // Fetch current time.
  397. if( m_reactor && m_reactor->m_running )
  398. // Can use reactor time to set up timeout.
  399. newtimeout->m_timeout = m_reactor->m_curtime;
  400. else if( clock_gettime(CLOCK_REALTIME, &newtimeout->m_timeout) == -1 )
  401. throw os_error("Failed to get current time from clock");
  402. } catch( ... ) {
  403. // Clean up timeout object that was created.
  404. if( m_reactor ) {
  405. // Push it to reactor queue.
  406. newtimeout->m_next = m_reactor->m_freetimeouts;
  407. m_reactor->m_freetimeouts = newtimeout;
  408. } else
  409. // Delete it (no reactor set up to attach it to).
  410. delete newtimeout;
  411. // Rethrow error.
  412. throw;
  413. }
  414. // Only add timeout if it is actually one (i.e., we're not setting
  415. // up a timeout in the past/now).
  416. if( msecs > 0 ) {
  417. // Initialize generic fields.
  418. newtimeout->m_timeout.tv_sec += msecs / 1000;
  419. newtimeout->m_timeout.tv_nsec += ( msecs % 1000 ) * 1000000l;
  420. newtimeout->m_id = m_nexttimeoutid++;
  421. // Limit timeout, calculating proper seconds (normalize it).
  422. if( newtimeout->m_timeout.tv_nsec >= 1000000000l ) {
  423. ++newtimeout->m_timeout.tv_sec;
  424. newtimeout->m_timeout.tv_nsec -= 1000000000l;
  425. }
  426. }
  427. // Walk list of timeouts, finding position.
  428. socket_timeout** instimeout = &m_nexttimeout;
  429. for( ; *instimeout; instimeout = &(*instimeout)->m_next ) {
  430. // Check next element for being after element to insert; if so,
  431. // stop advancing and do insert.
  432. const socket_timeout* const checktimeout = *instimeout;
  433. if( checktimeout->m_timeout.tv_sec > newtimeout->m_timeout.tv_sec ||
  434. ( checktimeout->m_timeout.tv_sec == newtimeout->m_timeout.tv_sec &&
  435. checktimeout->m_timeout.tv_nsec > newtimeout->m_timeout.tv_nsec ) )
  436. break;
  437. }
  438. // Update next of timeout fetched position.
  439. if( !( newtimeout->m_next = *instimeout ) ) {
  440. assert(!m_nexttimeout||m_lasttimeout==instimeout);
  441. m_lasttimeout = &newtimeout->m_next;
  442. }
  443. // Update new insert position, finalizing the after insert.
  444. debug("Attached timeout at %lu.%09lu as id %lu",
  445. newtimeout->m_timeout.tv_sec, newtimeout->m_timeout.tv_nsec,
  446. static_cast<unsigned long>(newtimeout->m_id));
  447. *instimeout = newtimeout;
  448. // Return timeout identifier.
  449. return newtimeout->m_id;
  450. }
  451. /**
  452. * Cancel timeout that's set up, walking tree and removing the specified
  453. * element.
  454. */
  455. void socket::canceltimeout(const size_t id) {
  456. // Walk list of timeouts, finding position.
  457. assert(!m_nexttimeout||m_lasttimeout);
  458. socket_timeout** deltimeout = &m_nexttimeout;
  459. for( ; *deltimeout; deltimeout = &(*deltimeout)->m_next ) {
  460. // Check whether this is the ID that matches.
  461. const socket_timeout* const checktimeout = *deltimeout;
  462. if( checktimeout->m_id == id )
  463. break;
  464. }
  465. // Check whether ID was found.
  466. socket_timeout* const remtimeout = *deltimeout;
  467. if( !remtimeout ) {
  468. debug("Failed to find timeout id %lu (not present), can't detach it",
  469. static_cast<unsigned long>(id));
  470. return;
  471. }
  472. // Update pointers.
  473. if( !( *deltimeout = remtimeout->m_next ) ) {
  474. // Need to update back of queue.
  475. assert(&remtimeout->m_next==m_lasttimeout);
  476. m_lasttimeout = deltimeout;
  477. }
  478. // Move timeout back to queue.
  479. if( m_reactor ) {
  480. // Push it to reactor.
  481. debug("Timeout %lu for %lu.%09lu detached from queue, put back on"
  482. " reactor set", remtimeout->m_timeout.tv_sec,
  483. remtimeout->m_timeout.tv_nsec, static_cast<unsigned long>(id));
  484. remtimeout->m_next = m_reactor->m_freetimeouts;
  485. m_reactor->m_freetimeouts = remtimeout;
  486. } else {
  487. // Destroy it, can't attach to reactor.
  488. debug("Timeout %lu for %lu.%09lu detached from queue, destroyed",
  489. remtimeout->m_timeout.tv_sec, remtimeout->m_timeout.tv_nsec,
  490. static_cast<unsigned long>(id));
  491. delete remtimeout;
  492. }
  493. }
  494. /**
  495. * Create a new socket of the specified domain, type and protocol, setting up
  496. * the descriptor state appropriately.
  497. */
  498. void socket::create(const int domain, const int type, const int protocol) {
  499. // Try to create the socket.
  500. if( m_fd >= 0 )
  501. throw state_error("Trying to create socket when socket is open");
  502. else if( ( m_fd = ::socket(domain, type, protocol) ) == -1 )
  503. throw os_error("Failed to initialize new socket of specified type");
  504. // Handle exceptions when attaching to clean up properly.
  505. debug("Created new socket for socket at %p, domain %i, type %i,"
  506. " protocol %i", static_cast<void*>(this), domain, type, protocol);
  507. try {
  508. // Try to set new socket to non-blocking.
  509. int flags;
  510. if( ( flags = fcntl(m_fd, F_GETFL) ) < 0 )
  511. throw os_error("Failed to get socket flags");
  512. else if( fcntl(m_fd, F_SETFL, flags | O_NONBLOCK) < 0 )
  513. throw os_error("Failed to set socket to non-blocking");
  514. // Check whether we need to acquire polling descriptor for it, and
  515. // reset events for newly created socket.
  516. m_events = 0;
  517. if( m_reactor )
  518. // Fetch poll descriptor by calling socket.
  519. m_fd = m_reactor->attachfd(m_fd, m_events);
  520. } catch( ... ) {
  521. // Clean up created descriptor on error (exceptions can only be
  522. // raised before the polling descriptor is successfully set up).
  523. ::close(m_fd);
  524. m_fd = -1;
  525. throw;
  526. }
  527. }
  528. /**
  529. * Set up socket option specified by the arguments.
  530. */
  531. void socket::setsockopt(const int level, const int optname, const int& val) {
  532. // Check for open socket.
  533. if( m_fd < 0 )
  534. throw state_error("Trying to bind socket when not created");
  535. // Set up socket option appropriately.
  536. assert(!m_reactor||(m_reactor->m_pollfds&&
  537. static_cast<size_t>(m_fd)<m_reactor->m_pollfdsize&&
  538. m_reactor->m_pollfds[m_fd].fd>=0));
  539. if( ::setsockopt(m_reactor ? m_reactor->m_pollfds[m_fd].fd : m_fd, level, optname, &val, sizeof(val)) == -1 )
  540. throw os_error("Failed to set socket option to specified value");
  541. debug("Set socket option %i/%i to %i for socket at %p", level, optname,
  542. val, static_cast<void*>(this));
  543. }
  544. /**
  545. * Bind open socket to the specified address.
  546. */
  547. void socket::bind(const sockaddr& addr, const socklen_t addrlen) {
  548. // Check for open socket.
  549. if( m_fd < 0 )
  550. throw state_error("Trying to bind socket when not created");
  551. // Bind according to reactor binding.
  552. assert(!m_reactor||(m_reactor->m_pollfds&&
  553. static_cast<size_t>(m_fd)<m_reactor->m_pollfdsize&&
  554. m_reactor->m_pollfds[m_fd].fd>=0));
  555. if( ::bind(m_reactor ? m_reactor->m_pollfds[m_fd].fd : m_fd, &addr, addrlen) == -1 )
  556. throw os_error("Failed to bind socket to passed address");
  557. debug("Bound socket at %p to specified address", static_cast<void*>(this));
  558. }
  559. /**
  560. * Set socket to listening state.
  561. */
  562. void socket::listen(const int backlog) {
  563. // Check for open socket.
  564. if( m_fd < 0 )
  565. throw state_error("Trying to bind socket when not created");
  566. // Set up listening state.
  567. assert(!m_reactor||(m_reactor->m_pollfds&&
  568. static_cast<size_t>(m_fd)<m_reactor->m_pollfdsize&&
  569. m_reactor->m_pollfds[m_fd].fd>=0));
  570. if( ::listen(m_reactor ? m_reactor->m_pollfds[m_fd].fd : m_fd, backlog) == -1 )
  571. throw os_error("Failed to initialize listening on socket");
  572. debug("Set up listening state with %i for socket at %p", backlog,
  573. static_cast<void*>(this));
  574. }
  575. /**
  576. * Accept incoming connection on the current socket, returning the accepted
  577. * file descriptor.
  578. */
  579. int socket::accept(sockaddr& addr, socklen_t& addrlen) {
  580. // Check for open socket.
  581. assert(addrlen>0);
  582. if( m_fd < 0 )
  583. throw state_error("Trying to bind socket when not created");
  584. // Accept connection.
  585. assert(!m_reactor||(m_reactor->m_pollfds&&
  586. static_cast<size_t>(m_fd)<m_reactor->m_pollfdsize&&
  587. m_reactor->m_pollfds[m_fd].fd>=0));
  588. int fd;
  589. if( ( fd = ::accept(m_reactor ? m_reactor->m_pollfds[m_fd].fd : m_fd, &addr, &addrlen) ) == -1 )
  590. throw os_error("Failed to accept new socket");
  591. // Return descriptor of accepted socket.
  592. debug("Accepted new incoming connection for socket at %p with fd %i",
  593. static_cast<void*>(this), fd);
  594. return fd;
  595. }
  596. /**
  597. * Read data from socket, setting it up in buffer.
  598. */
  599. ssize_t socket::read(void* const buf, const size_t len) {
  600. // Check for open socket.
  601. assert(!buf||len);
  602. if( m_fd < 0 )
  603. throw state_error("Trying to read from socket when not created");
  604. // Receive from socket.
  605. assert(!m_reactor||(m_reactor->m_pollfds&&
  606. static_cast<size_t>(m_fd)<m_reactor->m_pollfdsize&&
  607. m_reactor->m_pollfds[m_fd].fd>=0));
  608. ssize_t rcvd;
  609. if( ( rcvd = ::recv(m_reactor ? m_reactor->m_pollfds[m_fd].fd : m_fd, buf, len, 0) ) == -1 ) {
  610. // Check type of error.
  611. if( errno == EAGAIN || errno == EWOULDBLOCK )
  612. return 0;
  613. throw os_error("Failed to receive data on socket");
  614. }
  615. // Return received count, accounting for stream close.
  616. return rcvd > 0 ? rcvd : -1;
  617. }
  618. /**
  619. * Write data to socket, returning sent count.
  620. */
  621. ssize_t socket::write(const void* const buf, const size_t len) {
  622. // Check for open socket.
  623. assert(!buf||len);
  624. if( m_fd < 0 )
  625. throw state_error("Trying to write to socket when not created");
  626. // Send over socket.
  627. assert(!m_reactor||(m_reactor->m_pollfds&&
  628. static_cast<size_t>(m_fd)<m_reactor->m_pollfdsize&&
  629. m_reactor->m_pollfds[m_fd].fd>=0));
  630. ssize_t sent;
  631. if( ( sent = ::send(m_reactor ? m_reactor->m_pollfds[m_fd].fd : m_fd, buf, len, MSG_NOSIGNAL) ) == -1 ) {
  632. // Check type of error.
  633. if( errno == EAGAIN || errno == EWOULDBLOCK )
  634. return 0;
  635. throw os_error("Failed to send data on socket");
  636. }
  637. // Return actual sent count, accounting for stream close.
  638. return sent > 0 ? sent : -1;
  639. }
  640. /**
  641. * Close the current socket, cleaning up any remaining internal state.
  642. */
  643. void socket::close() {
  644. // Check for open socket and/or detach from reactor if required.
  645. if( m_fd < 0 )
  646. throw state_error("Trying to close socket when not created");
  647. else if( m_reactor )
  648. // Need to remove poll descriptor, store currently bound file
  649. // descriptor locally.
  650. m_fd = m_reactor->detachfd(m_fd);
  651. // Clean up the socket by closing it and resetting internal state.
  652. const int rv = ::close(m_fd);
  653. m_fd = -1;
  654. // Check for error on close.
  655. debug("Closed opened socket at %p", static_cast<void*>(this));
  656. if( rv < 0 )
  657. throw os_error("Failed to close open descriptor");
  658. }
  659. /**
  660. * Clean up socket by destroying remaining internal state.
  661. */
  662. socket::~socket() {
  663. // Check for detached socket; if not, detach socket now.
  664. if( m_reactor ) {
  665. // Detach descriptor if required, and detach socket from reactor
  666. // chain.
  667. if( m_fd >= 0 )
  668. m_fd = m_reactor->detachfd(m_fd);
  669. m_reactor->detachsock(this);
  670. // Place chain of timeout callbacks on reactor.
  671. if( m_nexttimeout ) {
  672. // Place all timeouts on reactor.
  673. assert(m_lasttimeout&&!*m_lasttimeout);
  674. *m_lasttimeout = m_reactor->m_freetimeouts;
  675. m_reactor->m_freetimeouts = m_nexttimeout;
  676. }
  677. } else {
  678. // Loop while timeout objects remain, destroying them.
  679. while( m_nexttimeout ) {
  680. // Fetch timeout.
  681. socket_timeout* const nexttimeout = m_nexttimeout;
  682. m_nexttimeout = nexttimeout->m_next;
  683. assert(m_nexttimeout||&nexttimeout->m_next==m_lasttimeout);
  684. // Destroy object.
  685. delete nexttimeout;
  686. }
  687. }
  688. // Close socket if not closed yet as final step, ignoring errors here.
  689. if( m_fd >= 0 )
  690. ::close(m_fd);
  691. }
  692. /**
  693. * Check whether socket is still opened.
  694. */
  695. bool socket::open() const {
  696. // Check open state.
  697. return m_fd >= 0;
  698. }
  699. /**
  700. * Check whether socket is currently attached.
  701. */
  702. bool socket::attached() const {
  703. // Check for reactor setup.
  704. return m_reactor;
  705. }
  706. /**
  707. * Detach socket from reactor, releasing any internal state that binds the
  708. * socket to the reactor.
  709. */
  710. void socket::detach() {
  711. // Check for bound reactor.
  712. if( !m_reactor )
  713. throw state_error("Trying to remove socket from reactor when not"
  714. " bound");
  715. else if( m_fd >= 0 )
  716. // Detach socket from reactor by unbinding it.
  717. m_fd = m_reactor->detachfd(m_fd);
  718. // Detach socket from reactor.
  719. m_reactor->detachsock(this);
  720. m_reactor = 0;
  721. // Dispatch callback to signal detachment.
  722. debug("Detached socket at %p from reactor", static_cast<void*>(this));
  723. handle_detach();
  724. }