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

/desktop/core/ext-py/Twisted/twisted/internet/tcp.py

https://github.com/qzem/hortonworks-sandbox
Python | 1033 lines | 899 code | 28 blank | 106 comment | 42 complexity | e13f0c80ba7d9633eb5e34043103e3e1 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, BSD-2-Clause, LGPL-2.1, Apache-2.0, BSD-3-Clause, MIT, GPL-2.0
  1. # -*- test-case-name: twisted.test.test_tcp -*-
  2. # Copyright (c) 2001-2007 Twisted Matrix Laboratories.
  3. # See LICENSE for details.
  4. """
  5. Various asynchronous TCP/IP classes.
  6. End users shouldn't use this module directly - use the reactor APIs instead.
  7. Maintainer: Itamar Shtull-Trauring
  8. """
  9. # System Imports
  10. import os
  11. import types
  12. import socket
  13. import sys
  14. import operator
  15. try:
  16. import fcntl
  17. except ImportError:
  18. fcntl = None
  19. from zope.interface import implements, classImplements
  20. try:
  21. from OpenSSL import SSL
  22. except ImportError:
  23. SSL = None
  24. from twisted.python.runtime import platformType
  25. if platformType == 'win32':
  26. # no such thing as WSAEPERM or error code 10001 according to winsock.h or MSDN
  27. EPERM = object()
  28. from errno import WSAEINVAL as EINVAL
  29. from errno import WSAEWOULDBLOCK as EWOULDBLOCK
  30. from errno import WSAEINPROGRESS as EINPROGRESS
  31. from errno import WSAEALREADY as EALREADY
  32. from errno import WSAECONNRESET as ECONNRESET
  33. from errno import WSAEISCONN as EISCONN
  34. from errno import WSAENOTCONN as ENOTCONN
  35. from errno import WSAEINTR as EINTR
  36. from errno import WSAENOBUFS as ENOBUFS
  37. from errno import WSAEMFILE as EMFILE
  38. # No such thing as WSAENFILE, either.
  39. ENFILE = object()
  40. # Nor ENOMEM
  41. ENOMEM = object()
  42. EAGAIN = EWOULDBLOCK
  43. from errno import WSAECONNRESET as ECONNABORTED
  44. from twisted.python.win32 import formatError as strerror
  45. else:
  46. from errno import EPERM
  47. from errno import EINVAL
  48. from errno import EWOULDBLOCK
  49. from errno import EINPROGRESS
  50. from errno import EALREADY
  51. from errno import ECONNRESET
  52. from errno import EISCONN
  53. from errno import ENOTCONN
  54. from errno import EINTR
  55. from errno import ENOBUFS
  56. from errno import EMFILE
  57. from errno import ENFILE
  58. from errno import ENOMEM
  59. from errno import EAGAIN
  60. from errno import ECONNABORTED
  61. from os import strerror
  62. from errno import errorcode
  63. # Twisted Imports
  64. from twisted.internet import defer, base, address
  65. from twisted.python import log, failure, reflect
  66. from twisted.python.util import unsignedID
  67. from twisted.internet.error import CannotListenError
  68. from twisted.internet import abstract, main, interfaces, error
  69. class _SocketCloser:
  70. _socketShutdownMethod = 'shutdown'
  71. def _closeSocket(self):
  72. # socket.close() doesn't *really* close if there's another reference
  73. # to it in the TCP/IP stack, e.g. if it was was inherited by a
  74. # subprocess. And we really do want to close the connection. So we
  75. # use shutdown() instead, and then close() in order to release the
  76. # filedescriptor.
  77. skt = self.socket
  78. try:
  79. getattr(skt, self._socketShutdownMethod)(2)
  80. except socket.error:
  81. pass
  82. try:
  83. skt.close()
  84. except socket.error:
  85. pass
  86. class _TLSMixin:
  87. _socketShutdownMethod = 'sock_shutdown'
  88. writeBlockedOnRead = 0
  89. readBlockedOnWrite = 0
  90. _userWantRead = _userWantWrite = True
  91. def getPeerCertificate(self):
  92. return self.socket.get_peer_certificate()
  93. def doRead(self):
  94. if self.disconnected:
  95. # See the comment in the similar check in doWrite below.
  96. # Additionally, in order for anything other than returning
  97. # CONNECTION_DONE here to make sense, it will probably be necessary
  98. # to implement a way to switch back to TCP from TLS (actually, if
  99. # we did something other than return CONNECTION_DONE, that would be
  100. # a big part of implementing that feature). In other words, the
  101. # expectation is that doRead will be called when self.disconnected
  102. # is True only when the connection has been lost. It's possible
  103. # that the other end could stop speaking TLS and then send us some
  104. # non-TLS data. We'll end up ignoring that data and dropping the
  105. # connection. There's no unit tests for this check in the cases
  106. # where it makes a difference. The test suite only hits this
  107. # codepath when it would have otherwise hit the SSL.ZeroReturnError
  108. # exception handler below, which has exactly the same behavior as
  109. # this conditional. Maybe that's the only case that can ever be
  110. # triggered, I'm not sure. -exarkun
  111. return main.CONNECTION_DONE
  112. if self.writeBlockedOnRead:
  113. self.writeBlockedOnRead = 0
  114. self._resetReadWrite()
  115. try:
  116. return Connection.doRead(self)
  117. except SSL.ZeroReturnError:
  118. return main.CONNECTION_DONE
  119. except SSL.WantReadError:
  120. return
  121. except SSL.WantWriteError:
  122. self.readBlockedOnWrite = 1
  123. Connection.startWriting(self)
  124. Connection.stopReading(self)
  125. return
  126. except SSL.SysCallError, (retval, desc):
  127. if ((retval == -1 and desc == 'Unexpected EOF')
  128. or retval > 0):
  129. return main.CONNECTION_LOST
  130. log.err()
  131. return main.CONNECTION_LOST
  132. except SSL.Error, e:
  133. return e
  134. def doWrite(self):
  135. # Retry disconnecting
  136. if self.disconnected:
  137. # This case is triggered when "disconnected" is set to True by a
  138. # call to _postLoseConnection from FileDescriptor.doWrite (to which
  139. # we upcall at the end of this overridden version of that API). It
  140. # means that while, as far as any protocol connected to this
  141. # transport is concerned, the connection no longer exists, the
  142. # connection *does* actually still exist. Instead of closing the
  143. # connection in the overridden _postLoseConnection, we probably
  144. # tried (and failed) to send a TLS close alert. The TCP connection
  145. # is still up and we're waiting for the socket to become writeable
  146. # enough for the TLS close alert to actually be sendable. Only
  147. # then will the connection actually be torn down. -exarkun
  148. return self._postLoseConnection()
  149. if self._writeDisconnected:
  150. return self._closeWriteConnection()
  151. if self.readBlockedOnWrite:
  152. self.readBlockedOnWrite = 0
  153. self._resetReadWrite()
  154. return Connection.doWrite(self)
  155. def writeSomeData(self, data):
  156. try:
  157. return Connection.writeSomeData(self, data)
  158. except SSL.WantWriteError:
  159. return 0
  160. except SSL.WantReadError:
  161. self.writeBlockedOnRead = 1
  162. Connection.stopWriting(self)
  163. Connection.startReading(self)
  164. return 0
  165. except SSL.ZeroReturnError:
  166. return main.CONNECTION_LOST
  167. except SSL.SysCallError, e:
  168. if e[0] == -1 and data == "":
  169. # errors when writing empty strings are expected
  170. # and can be ignored
  171. return 0
  172. else:
  173. return main.CONNECTION_LOST
  174. except SSL.Error, e:
  175. return e
  176. def _postLoseConnection(self):
  177. """
  178. Gets called after loseConnection(), after buffered data is sent.
  179. We try to send an SSL shutdown alert, but if it doesn't work, retry
  180. when the socket is writable.
  181. """
  182. # Here, set "disconnected" to True to trick higher levels into thinking
  183. # the connection is really gone. It's not, and we're not going to
  184. # close it yet. Instead, we'll try to send a TLS close alert to shut
  185. # down the TLS connection cleanly. Only after we actually get the
  186. # close alert into the socket will we disconnect the underlying TCP
  187. # connection.
  188. self.disconnected = True
  189. if hasattr(self.socket, 'set_shutdown'):
  190. # If possible, mark the state of the TLS connection as having
  191. # already received a TLS close alert from the peer. Why do
  192. # this???
  193. self.socket.set_shutdown(SSL.RECEIVED_SHUTDOWN)
  194. return self._sendCloseAlert()
  195. def _sendCloseAlert(self):
  196. # Okay, *THIS* is a bit complicated.
  197. # Basically, the issue is, OpenSSL seems to not actually return
  198. # errors from SSL_shutdown. Therefore, the only way to
  199. # determine if the close notification has been sent is by
  200. # SSL_shutdown returning "done". However, it will not claim it's
  201. # done until it's both sent *and* received a shutdown notification.
  202. # I don't actually want to wait for a received shutdown
  203. # notification, though, so, I have to set RECEIVED_SHUTDOWN
  204. # before calling shutdown. Then, it'll return True once it's
  205. # *SENT* the shutdown.
  206. # However, RECEIVED_SHUTDOWN can't be left set, because then
  207. # reads will fail, breaking half close.
  208. # Also, since shutdown doesn't report errors, an empty write call is
  209. # done first, to try to detect if the connection has gone away.
  210. # (*NOT* an SSL_write call, because that fails once you've called
  211. # shutdown)
  212. try:
  213. os.write(self.socket.fileno(), '')
  214. except OSError, se:
  215. if se.args[0] in (EINTR, EWOULDBLOCK, ENOBUFS):
  216. return 0
  217. # Write error, socket gone
  218. return main.CONNECTION_LOST
  219. try:
  220. if hasattr(self.socket, 'set_shutdown'):
  221. laststate = self.socket.get_shutdown()
  222. self.socket.set_shutdown(laststate | SSL.RECEIVED_SHUTDOWN)
  223. done = self.socket.shutdown()
  224. if not (laststate & SSL.RECEIVED_SHUTDOWN):
  225. self.socket.set_shutdown(SSL.SENT_SHUTDOWN)
  226. else:
  227. #warnings.warn("SSL connection shutdown possibly unreliable, "
  228. # "please upgrade to ver 0.XX", category=UserWarning)
  229. self.socket.shutdown()
  230. done = True
  231. except SSL.Error, e:
  232. return e
  233. if done:
  234. self.stopWriting()
  235. # Note that this is tested for by identity below.
  236. return main.CONNECTION_DONE
  237. else:
  238. # For some reason, the close alert wasn't sent. Start writing
  239. # again so that we'll get another chance to send it.
  240. self.startWriting()
  241. # On Linux, select will sometimes not report a closed file
  242. # descriptor in the write set (in particular, it seems that if a
  243. # send() fails with EPIPE, the socket will not appear in the write
  244. # set). The shutdown call above (which calls down to SSL_shutdown)
  245. # may have swallowed a write error. Therefore, also start reading
  246. # so that if the socket is closed we will notice. This doesn't
  247. # seem to be a problem for poll (because poll reports errors
  248. # separately) or with select on BSD (presumably because, unlike
  249. # Linux, it doesn't implement select in terms of poll and then map
  250. # POLLHUP to select's in fd_set).
  251. self.startReading()
  252. return None
  253. def _closeWriteConnection(self):
  254. result = self._sendCloseAlert()
  255. if result is main.CONNECTION_DONE:
  256. return Connection._closeWriteConnection(self)
  257. return result
  258. def startReading(self):
  259. self._userWantRead = True
  260. if not self.readBlockedOnWrite:
  261. return Connection.startReading(self)
  262. def stopReading(self):
  263. self._userWantRead = False
  264. if not self.writeBlockedOnRead:
  265. return Connection.stopReading(self)
  266. def startWriting(self):
  267. self._userWantWrite = True
  268. if not self.writeBlockedOnRead:
  269. return Connection.startWriting(self)
  270. def stopWriting(self):
  271. self._userWantWrite = False
  272. if not self.readBlockedOnWrite:
  273. return Connection.stopWriting(self)
  274. def _resetReadWrite(self):
  275. # After changing readBlockedOnWrite or writeBlockedOnRead,
  276. # call this to reset the state to what the user requested.
  277. if self._userWantWrite:
  278. self.startWriting()
  279. else:
  280. self.stopWriting()
  281. if self._userWantRead:
  282. self.startReading()
  283. else:
  284. self.stopReading()
  285. class _TLSDelayed(object):
  286. """
  287. State tracking record for TLS startup parameters. Used to remember how
  288. TLS should be started when starting it is delayed to wait for the output
  289. buffer to be flushed.
  290. @ivar bufferedData: A C{list} which contains all the data which was
  291. written to the transport after an attempt to start TLS was made but
  292. before the buffers outstanding at that time could be flushed and TLS
  293. could really be started. This is appended to by the transport's
  294. write and writeSequence methods until it is possible to actually
  295. start TLS, then it is written to the TLS-enabled transport.
  296. @ivar context: An SSL context factory object to use to start TLS.
  297. @ivar extra: An extra argument to pass to the transport's C{startTLS}
  298. method.
  299. """
  300. def __init__(self, bufferedData, context, extra):
  301. self.bufferedData = bufferedData
  302. self.context = context
  303. self.extra = extra
  304. def _getTLSClass(klass, _existing={}):
  305. if klass not in _existing:
  306. class TLSConnection(_TLSMixin, klass):
  307. implements(interfaces.ISSLTransport)
  308. _existing[klass] = TLSConnection
  309. return _existing[klass]
  310. class Connection(abstract.FileDescriptor, _SocketCloser):
  311. """
  312. Superclass of all socket-based FileDescriptors.
  313. This is an abstract superclass of all objects which represent a TCP/IP
  314. connection based socket.
  315. @ivar logstr: prefix used when logging events related to this connection.
  316. @type logstr: C{str}
  317. """
  318. implements(interfaces.ITCPTransport, interfaces.ISystemHandle)
  319. TLS = 0
  320. def __init__(self, skt, protocol, reactor=None):
  321. abstract.FileDescriptor.__init__(self, reactor=reactor)
  322. self.socket = skt
  323. self.socket.setblocking(0)
  324. self.fileno = skt.fileno
  325. self.protocol = protocol
  326. if SSL:
  327. _tlsWaiting = None
  328. def startTLS(self, ctx, extra):
  329. assert not self.TLS
  330. if self.dataBuffer or self._tempDataBuffer:
  331. # pre-TLS bytes are still being written. Starting TLS now
  332. # will do the wrong thing. Instead, mark that we're trying
  333. # to go into the TLS state.
  334. self._tlsWaiting = _TLSDelayed([], ctx, extra)
  335. return False
  336. self.stopReading()
  337. self.stopWriting()
  338. self._startTLS()
  339. self.socket = SSL.Connection(ctx.getContext(), self.socket)
  340. self.fileno = self.socket.fileno
  341. self.startReading()
  342. return True
  343. def _startTLS(self):
  344. self.TLS = 1
  345. self.__class__ = _getTLSClass(self.__class__)
  346. def write(self, bytes):
  347. if self._tlsWaiting is not None:
  348. self._tlsWaiting.bufferedData.append(bytes)
  349. else:
  350. abstract.FileDescriptor.write(self, bytes)
  351. def writeSequence(self, iovec):
  352. if self._tlsWaiting is not None:
  353. self._tlsWaiting.bufferedData.extend(iovec)
  354. else:
  355. abstract.FileDescriptor.writeSequence(self, iovec)
  356. def doWrite(self):
  357. result = abstract.FileDescriptor.doWrite(self)
  358. if self._tlsWaiting is not None:
  359. if not self.dataBuffer and not self._tempDataBuffer:
  360. waiting = self._tlsWaiting
  361. self._tlsWaiting = None
  362. self.startTLS(waiting.context, waiting.extra)
  363. self.writeSequence(waiting.bufferedData)
  364. return result
  365. def getHandle(self):
  366. """Return the socket for this connection."""
  367. return self.socket
  368. def doRead(self):
  369. """Calls self.protocol.dataReceived with all available data.
  370. This reads up to self.bufferSize bytes of data from its socket, then
  371. calls self.dataReceived(data) to process it. If the connection is not
  372. lost through an error in the physical recv(), this function will return
  373. the result of the dataReceived call.
  374. """
  375. try:
  376. data = self.socket.recv(self.bufferSize)
  377. except socket.error, se:
  378. if se.args[0] == EWOULDBLOCK:
  379. return
  380. else:
  381. return main.CONNECTION_LOST
  382. if not data:
  383. return main.CONNECTION_DONE
  384. return self.protocol.dataReceived(data)
  385. def writeSomeData(self, data):
  386. """Connection.writeSomeData(data) -> #of bytes written | CONNECTION_LOST
  387. This writes as much data as possible to the socket and returns either
  388. the number of bytes read (which is positive) or a connection error code
  389. (which is negative)
  390. """
  391. try:
  392. # Limit length of buffer to try to send, because some OSes are too
  393. # stupid to do so themselves (ahem windows)
  394. return self.socket.send(buffer(data, 0, self.SEND_LIMIT))
  395. except socket.error, se:
  396. if se.args[0] == EINTR:
  397. return self.writeSomeData(data)
  398. elif se.args[0] in (EWOULDBLOCK, ENOBUFS):
  399. return 0
  400. else:
  401. return main.CONNECTION_LOST
  402. def _closeWriteConnection(self):
  403. try:
  404. getattr(self.socket, self._socketShutdownMethod)(1)
  405. except socket.error:
  406. pass
  407. p = interfaces.IHalfCloseableProtocol(self.protocol, None)
  408. if p:
  409. try:
  410. p.writeConnectionLost()
  411. except:
  412. f = failure.Failure()
  413. log.err()
  414. self.connectionLost(f)
  415. def readConnectionLost(self, reason):
  416. p = interfaces.IHalfCloseableProtocol(self.protocol, None)
  417. if p:
  418. try:
  419. p.readConnectionLost()
  420. except:
  421. log.err()
  422. self.connectionLost(failure.Failure())
  423. else:
  424. self.connectionLost(reason)
  425. def connectionLost(self, reason):
  426. """See abstract.FileDescriptor.connectionLost().
  427. """
  428. abstract.FileDescriptor.connectionLost(self, reason)
  429. self._closeSocket()
  430. protocol = self.protocol
  431. del self.protocol
  432. del self.socket
  433. del self.fileno
  434. protocol.connectionLost(reason)
  435. logstr = "Uninitialized"
  436. def logPrefix(self):
  437. """Return the prefix to log with when I own the logging thread.
  438. """
  439. return self.logstr
  440. def getTcpNoDelay(self):
  441. return operator.truth(self.socket.getsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY))
  442. def setTcpNoDelay(self, enabled):
  443. self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, enabled)
  444. def getTcpKeepAlive(self):
  445. return operator.truth(self.socket.getsockopt(socket.SOL_SOCKET,
  446. socket.SO_KEEPALIVE))
  447. def setTcpKeepAlive(self, enabled):
  448. self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, enabled)
  449. if SSL:
  450. classImplements(Connection, interfaces.ITLSTransport)
  451. class BaseClient(Connection):
  452. """A base class for client TCP (and similiar) sockets.
  453. """
  454. addressFamily = socket.AF_INET
  455. socketType = socket.SOCK_STREAM
  456. def _finishInit(self, whenDone, skt, error, reactor):
  457. """Called by base classes to continue to next stage of initialization."""
  458. if whenDone:
  459. Connection.__init__(self, skt, None, reactor)
  460. self.doWrite = self.doConnect
  461. self.doRead = self.doConnect
  462. reactor.callLater(0, whenDone)
  463. else:
  464. reactor.callLater(0, self.failIfNotConnected, error)
  465. def startTLS(self, ctx, client=1):
  466. if Connection.startTLS(self, ctx, client):
  467. if client:
  468. self.socket.set_connect_state()
  469. else:
  470. self.socket.set_accept_state()
  471. def stopConnecting(self):
  472. """Stop attempt to connect."""
  473. self.failIfNotConnected(error.UserError())
  474. def failIfNotConnected(self, err):
  475. """
  476. Generic method called when the attemps to connect failed. It basically
  477. cleans everything it can: call connectionFailed, stop read and write,
  478. delete socket related members.
  479. """
  480. if (self.connected or self.disconnected or
  481. not hasattr(self, "connector")):
  482. return
  483. self.connector.connectionFailed(failure.Failure(err))
  484. if hasattr(self, "reactor"):
  485. # this doesn't happen if we failed in __init__
  486. self.stopReading()
  487. self.stopWriting()
  488. del self.connector
  489. try:
  490. self._closeSocket()
  491. except AttributeError:
  492. pass
  493. else:
  494. del self.socket, self.fileno
  495. def createInternetSocket(self):
  496. """(internal) Create a non-blocking socket using
  497. self.addressFamily, self.socketType.
  498. """
  499. s = socket.socket(self.addressFamily, self.socketType)
  500. s.setblocking(0)
  501. if fcntl and hasattr(fcntl, 'FD_CLOEXEC'):
  502. old = fcntl.fcntl(s.fileno(), fcntl.F_GETFD)
  503. fcntl.fcntl(s.fileno(), fcntl.F_SETFD, old | fcntl.FD_CLOEXEC)
  504. return s
  505. def resolveAddress(self):
  506. if abstract.isIPAddress(self.addr[0]):
  507. self._setRealAddress(self.addr[0])
  508. else:
  509. d = self.reactor.resolve(self.addr[0])
  510. d.addCallbacks(self._setRealAddress, self.failIfNotConnected)
  511. def _setRealAddress(self, address):
  512. self.realAddress = (address, self.addr[1])
  513. self.doConnect()
  514. def doConnect(self):
  515. """I connect the socket.
  516. Then, call the protocol's makeConnection, and start waiting for data.
  517. """
  518. if not hasattr(self, "connector"):
  519. # this happens when connection failed but doConnect
  520. # was scheduled via a callLater in self._finishInit
  521. return
  522. err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
  523. if err:
  524. self.failIfNotConnected(error.getConnectError((err, strerror(err))))
  525. return
  526. # doConnect gets called twice. The first time we actually need to
  527. # start the connection attempt. The second time we don't really
  528. # want to (SO_ERROR above will have taken care of any errors, and if
  529. # it reported none, the mere fact that doConnect was called again is
  530. # sufficient to indicate that the connection has succeeded), but it
  531. # is not /particularly/ detrimental to do so. This should get
  532. # cleaned up some day, though.
  533. try:
  534. connectResult = self.socket.connect_ex(self.realAddress)
  535. except socket.error, se:
  536. connectResult = se.args[0]
  537. if connectResult:
  538. if connectResult == EISCONN:
  539. pass
  540. # on Windows EINVAL means sometimes that we should keep trying:
  541. # http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/connect_2.asp
  542. elif ((connectResult in (EWOULDBLOCK, EINPROGRESS, EALREADY)) or
  543. (connectResult == EINVAL and platformType == "win32")):
  544. self.startReading()
  545. self.startWriting()
  546. return
  547. else:
  548. self.failIfNotConnected(error.getConnectError((connectResult, strerror(connectResult))))
  549. return
  550. # If I have reached this point without raising or returning, that means
  551. # that the socket is connected.
  552. del self.doWrite
  553. del self.doRead
  554. # we first stop and then start, to reset any references to the old doRead
  555. self.stopReading()
  556. self.stopWriting()
  557. self._connectDone()
  558. def _connectDone(self):
  559. self.protocol = self.connector.buildProtocol(self.getPeer())
  560. self.connected = 1
  561. self.logstr = self.protocol.__class__.__name__ + ",client"
  562. self.startReading()
  563. self.protocol.makeConnection(self)
  564. def connectionLost(self, reason):
  565. if not self.connected:
  566. self.failIfNotConnected(error.ConnectError(string=reason))
  567. else:
  568. Connection.connectionLost(self, reason)
  569. self.connector.connectionLost(reason)
  570. class Client(BaseClient):
  571. """A TCP client."""
  572. def __init__(self, host, port, bindAddress, connector, reactor=None):
  573. # BaseClient.__init__ is invoked later
  574. self.connector = connector
  575. self.addr = (host, port)
  576. whenDone = self.resolveAddress
  577. err = None
  578. skt = None
  579. try:
  580. skt = self.createInternetSocket()
  581. except socket.error, se:
  582. err = error.ConnectBindError(se[0], se[1])
  583. whenDone = None
  584. if whenDone and bindAddress is not None:
  585. try:
  586. skt.bind(bindAddress)
  587. except socket.error, se:
  588. err = error.ConnectBindError(se[0], se[1])
  589. whenDone = None
  590. self._finishInit(whenDone, skt, err, reactor)
  591. def getHost(self):
  592. """Returns an IPv4Address.
  593. This indicates the address from which I am connecting.
  594. """
  595. return address.IPv4Address('TCP', *(self.socket.getsockname() + ('INET',)))
  596. def getPeer(self):
  597. """Returns an IPv4Address.
  598. This indicates the address that I am connected to.
  599. """
  600. return address.IPv4Address('TCP', *(self.realAddress + ('INET',)))
  601. def __repr__(self):
  602. s = '<%s to %s at %x>' % (self.__class__, self.addr, unsignedID(self))
  603. return s
  604. class Server(Connection):
  605. """
  606. Serverside socket-stream connection class.
  607. This is a serverside network connection transport; a socket which came from
  608. an accept() on a server.
  609. """
  610. def __init__(self, sock, protocol, client, server, sessionno, reactor):
  611. """
  612. Server(sock, protocol, client, server, sessionno)
  613. Initialize it with a socket, a protocol, a descriptor for my peer (a
  614. tuple of host, port describing the other end of the connection), an
  615. instance of Port, and a session number.
  616. """
  617. Connection.__init__(self, sock, protocol, reactor)
  618. self.server = server
  619. self.client = client
  620. self.sessionno = sessionno
  621. self.hostname = client[0]
  622. self.logstr = "%s,%s,%s" % (self.protocol.__class__.__name__,
  623. sessionno,
  624. self.hostname)
  625. self.repstr = "<%s #%s on %s>" % (self.protocol.__class__.__name__,
  626. self.sessionno,
  627. self.server._realPortNumber)
  628. self.startReading()
  629. self.connected = 1
  630. def __repr__(self):
  631. """A string representation of this connection.
  632. """
  633. return self.repstr
  634. def startTLS(self, ctx, server=1):
  635. if Connection.startTLS(self, ctx, server):
  636. if server:
  637. self.socket.set_accept_state()
  638. else:
  639. self.socket.set_connect_state()
  640. def getHost(self):
  641. """Returns an IPv4Address.
  642. This indicates the server's address.
  643. """
  644. return address.IPv4Address('TCP', *(self.socket.getsockname() + ('INET',)))
  645. def getPeer(self):
  646. """Returns an IPv4Address.
  647. This indicates the client's address.
  648. """
  649. return address.IPv4Address('TCP', *(self.client + ('INET',)))
  650. class Port(base.BasePort, _SocketCloser):
  651. """
  652. A TCP server port, listening for connections.
  653. When a connection is accepted, this will call a factory's buildProtocol
  654. with the incoming address as an argument, according to the specification
  655. described in L{twisted.internet.interfaces.IProtocolFactory}.
  656. If you wish to change the sort of transport that will be used, the
  657. C{transport} attribute will be called with the signature expected for
  658. C{Server.__init__}, so it can be replaced.
  659. @ivar deferred: a deferred created when L{stopListening} is called, and
  660. that will fire when connection is lost. This is not to be used it
  661. directly: prefer the deferred returned by L{stopListening} instead.
  662. @type deferred: L{defer.Deferred}
  663. @ivar disconnecting: flag indicating that the L{stopListening} method has
  664. been called and that no connections should be accepted anymore.
  665. @type disconnecting: C{bool}
  666. @ivar connected: flag set once the listen has successfully been called on
  667. the socket.
  668. @type connected: C{bool}
  669. """
  670. implements(interfaces.IListeningPort)
  671. addressFamily = socket.AF_INET
  672. socketType = socket.SOCK_STREAM
  673. transport = Server
  674. sessionno = 0
  675. interface = ''
  676. backlog = 50
  677. # Actual port number being listened on, only set to a non-None
  678. # value when we are actually listening.
  679. _realPortNumber = None
  680. def __init__(self, port, factory, backlog=50, interface='', reactor=None):
  681. """Initialize with a numeric port to listen on.
  682. """
  683. base.BasePort.__init__(self, reactor=reactor)
  684. self.port = port
  685. self.factory = factory
  686. self.backlog = backlog
  687. self.interface = interface
  688. def __repr__(self):
  689. if self._realPortNumber is not None:
  690. return "<%s of %s on %s>" % (self.__class__, self.factory.__class__,
  691. self._realPortNumber)
  692. else:
  693. return "<%s of %s (not listening)>" % (self.__class__, self.factory.__class__)
  694. def createInternetSocket(self):
  695. s = base.BasePort.createInternetSocket(self)
  696. if platformType == "posix" and sys.platform != "cygwin":
  697. s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  698. return s
  699. def startListening(self):
  700. """Create and bind my socket, and begin listening on it.
  701. This is called on unserialization, and must be called after creating a
  702. server to begin listening on the specified port.
  703. """
  704. try:
  705. skt = self.createInternetSocket()
  706. skt.bind((self.interface, self.port))
  707. except socket.error, le:
  708. raise CannotListenError, (self.interface, self.port, le)
  709. # Make sure that if we listened on port 0, we update that to
  710. # reflect what the OS actually assigned us.
  711. self._realPortNumber = skt.getsockname()[1]
  712. log.msg("%s starting on %s" % (self.factory.__class__, self._realPortNumber))
  713. # The order of the next 6 lines is kind of bizarre. If no one
  714. # can explain it, perhaps we should re-arrange them.
  715. self.factory.doStart()
  716. skt.listen(self.backlog)
  717. self.connected = True
  718. self.socket = skt
  719. self.fileno = self.socket.fileno
  720. self.numberAccepts = 100
  721. self.startReading()
  722. def _buildAddr(self, (host, port)):
  723. return address._ServerFactoryIPv4Address('TCP', host, port)
  724. def doRead(self):
  725. """Called when my socket is ready for reading.
  726. This accepts a connection and calls self.protocol() to handle the
  727. wire-level protocol.
  728. """
  729. try:
  730. if platformType == "posix":
  731. numAccepts = self.numberAccepts
  732. else:
  733. # win32 event loop breaks if we do more than one accept()
  734. # in an iteration of the event loop.
  735. numAccepts = 1
  736. for i in range(numAccepts):
  737. # we need this so we can deal with a factory's buildProtocol
  738. # calling our loseConnection
  739. if self.disconnecting:
  740. return
  741. try:
  742. skt, addr = self.socket.accept()
  743. except socket.error, e:
  744. if e.args[0] in (EWOULDBLOCK, EAGAIN):
  745. self.numberAccepts = i
  746. break
  747. elif e.args[0] == EPERM:
  748. # Netfilter on Linux may have rejected the
  749. # connection, but we get told to try to accept()
  750. # anyway.
  751. continue
  752. elif e.args[0] in (EMFILE, ENOBUFS, ENFILE, ENOMEM, ECONNABORTED):
  753. # Linux gives EMFILE when a process is not allowed
  754. # to allocate any more file descriptors. *BSD and
  755. # Win32 give (WSA)ENOBUFS. Linux can also give
  756. # ENFILE if the system is out of inodes, or ENOMEM
  757. # if there is insufficient memory to allocate a new
  758. # dentry. ECONNABORTED is documented as possible on
  759. # both Linux and Windows, but it is not clear
  760. # whether there are actually any circumstances under
  761. # which it can happen (one might expect it to be
  762. # possible if a client sends a FIN or RST after the
  763. # server sends a SYN|ACK but before application code
  764. # calls accept(2), however at least on Linux this
  765. # _seems_ to be short-circuited by syncookies.
  766. log.msg("Could not accept new connection (%s)" % (
  767. errorcode[e.args[0]],))
  768. break
  769. raise
  770. protocol = self.factory.buildProtocol(self._buildAddr(addr))
  771. if protocol is None:
  772. skt.close()
  773. continue
  774. s = self.sessionno
  775. self.sessionno = s+1
  776. transport = self.transport(skt, protocol, addr, self, s, self.reactor)
  777. transport = self._preMakeConnection(transport)
  778. protocol.makeConnection(transport)
  779. else:
  780. self.numberAccepts = self.numberAccepts+20
  781. except:
  782. # Note that in TLS mode, this will possibly catch SSL.Errors
  783. # raised by self.socket.accept()
  784. #
  785. # There is no "except SSL.Error:" above because SSL may be
  786. # None if there is no SSL support. In any case, all the
  787. # "except SSL.Error:" suite would probably do is log.deferr()
  788. # and return, so handling it here works just as well.
  789. log.deferr()
  790. def _preMakeConnection(self, transport):
  791. return transport
  792. def loseConnection(self, connDone=failure.Failure(main.CONNECTION_DONE)):
  793. """
  794. Stop accepting connections on this port.
  795. This will shut down the socket and call self.connectionLost(). It
  796. returns a deferred which will fire successfully when the port is
  797. actually closed.
  798. """
  799. self.disconnecting = True
  800. self.stopReading()
  801. if self.connected:
  802. self.deferred = defer.Deferred()
  803. self.reactor.callLater(0, self.connectionLost, connDone)
  804. return self.deferred
  805. stopListening = loseConnection
  806. def connectionLost(self, reason):
  807. """
  808. Cleans up the socket.
  809. """
  810. log.msg('(Port %s Closed)' % self._realPortNumber)
  811. self._realPortNumber = None
  812. d = None
  813. if hasattr(self, "deferred"):
  814. d = self.deferred
  815. del self.deferred
  816. base.BasePort.connectionLost(self, reason)
  817. self.connected = False
  818. self._closeSocket()
  819. del self.socket
  820. del self.fileno
  821. try:
  822. self.factory.doStop()
  823. except:
  824. self.disconnecting = False
  825. if d is not None:
  826. d.errback(failure.Failure())
  827. else:
  828. raise
  829. else:
  830. self.disconnecting = False
  831. if d is not None:
  832. d.callback(None)
  833. def logPrefix(self):
  834. """Returns the name of my class, to prefix log entries with.
  835. """
  836. return reflect.qual(self.factory.__class__)
  837. def getHost(self):
  838. """Returns an IPv4Address.
  839. This indicates the server's address.
  840. """
  841. return address.IPv4Address('TCP', *(self.socket.getsockname() + ('INET',)))
  842. class Connector(base.BaseConnector):
  843. def __init__(self, host, port, factory, timeout, bindAddress, reactor=None):
  844. self.host = host
  845. if isinstance(port, types.StringTypes):
  846. try:
  847. port = socket.getservbyname(port, 'tcp')
  848. except socket.error, e:
  849. raise error.ServiceNameUnknownError(string="%s (%r)" % (e, port))
  850. self.port = port
  851. self.bindAddress = bindAddress
  852. base.BaseConnector.__init__(self, factory, timeout, reactor)
  853. def _makeTransport(self):
  854. return Client(self.host, self.port, self.bindAddress, self, self.reactor)
  855. def getDestination(self):
  856. return address.IPv4Address('TCP', self.host, self.port, 'INET')