5
Created by Thomas Mangin on 2013-07-11.
6
Copyright (c) 2013-2013 Exa Networks. All rights reserved.
11
from exabgp.util.errstr import errstr
13
from exabgp.protocol.family import AFI
14
#from exabgp.util.coroutine import each
15
from exabgp.util.ip import isipv4,isipv6
16
from exabgp.reactor.network.error import error,errno,NetworkError,BindingError,AcceptError
17
from exabgp.reactor.network.incoming import Incoming
18
#from exabgp.bgp.message.open import Open
19
#from exabgp.bgp.message.notification import Notify
21
from exabgp.logger import Logger
24
class Listener (object):
25
def __init__ (self,hosts,port,backlog=200):
28
self._backlog = backlog
33
self.logger = Logger()
35
def _bind (self,ip,port):
38
s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM, socket.IPPROTO_TCP)
40
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
41
except (socket.error,AttributeError):
45
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP)
47
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
48
except (socket.error,AttributeError):
55
s.listen(self._backlog)
57
except socket.error, e:
58
if e.args[0] == errno.EADDRINUSE:
59
raise BindingError('could not listen on %s:%d, the port already in use by another application' % (ip,self._port))
60
elif e.args[0] == errno.EADDRNOTAVAIL:
61
raise BindingError('could not listen on %s:%d, this is an invalid address' % (ip,self._port))
63
raise BindingError('could not listen on %s:%d (%s)' % (ip,self._port,errstr(e)))
67
for host in self._hosts:
68
if (host,self._port) not in self._sockets:
69
s = self._bind(host,self._port)
70
self._sockets[s] = (host,self._port)
72
except NetworkError,e:
73
self.logger.network(str(e),'critical')
83
for sock,(host,_) in self._sockets.items():
86
local_ip,local_port = io.getpeername()
87
remote_ip,remote_port = io.getsockname()
88
yield Incoming(AFI.ipv4,remote_ip,local_ip,io)
90
except socket.error, e:
91
if e.errno in error.block:
93
raise AcceptError('could not accept a new connection (%s)' % errstr(e))
94
except NetworkError,e:
95
self.logger.network(str(e),'critical')
102
for sock,(ip,port) in self._sockets.items():
104
self.logger.network('stopped listening on %s:%d' % (ip,port),'info')