diff options
author | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2014-06-15 21:22:35 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2014-06-16 08:11:41 +0900 |
commit | f513b8751ddde0274203b589057da40e82ac9275 (patch) | |
tree | 9d221bdd70f20893fffc1a60fd344537257bd76f | |
parent | 783663afb29ebd0abeaae7792d924b65bc72db14 (diff) |
bgp: use sendall with lock
With the current design, multiple greenlets calls sendall() on a
single tcp socket. This leads to a corrupted bgp message.
This patch introduces mutex to work around the problem. However, I
hope that we _fix_ the design where only one greenlet call sendall()
on a signel tcp socket in the future.
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r-- | ryu/services/protocols/bgp/speaker.py | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/ryu/services/protocols/bgp/speaker.py b/ryu/services/protocols/bgp/speaker.py index d5a543ad..e4a9bc92 100644 --- a/ryu/services/protocols/bgp/speaker.py +++ b/ryu/services/protocols/bgp/speaker.py @@ -21,6 +21,7 @@ import socket import struct import traceback from socket import IPPROTO_TCP, TCP_NODELAY +from eventlet import semaphore from ryu.lib.packet import bgp from ryu.lib.packet.bgp import RouteFamily @@ -104,6 +105,7 @@ class BgpProtocol(Protocol, Activity): self._recv_buff = '' self._socket = socket self._socket.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1) + self._sendlock = semaphore.Semaphore() self._signal_bus = signal_bus self._holdtime = None self._keepalive = None @@ -362,7 +364,7 @@ class BgpProtocol(Protocol, Activity): """ notification = BGPNotification(code, subcode) reason = notification.reason - self._socket.sendall(notification.serialize()) + self._send_with_lock(notification) self._signal_bus.bgp_error(self._peer, code, subcode, reason) LOG.error( 'Sent notification to %r >> %s' % @@ -370,6 +372,13 @@ class BgpProtocol(Protocol, Activity): ) self._socket.close() + def _send_with_lock(self, msg): + self._sendlock.acquire() + try: + self._socket.sendall(msg.serialize()) + finally: + self._sendlock.release() + def send(self, msg): if not self.started: raise BgpProtocolException('Tried to send message to peer when ' @@ -378,7 +387,7 @@ class BgpProtocol(Protocol, Activity): # get peername before senging msg because sending msg can occur # conncetion lost peername = self.get_peername() - self._socket.sendall(msg.serialize()) + self._send_with_lock(msg) if msg.type == BGP_MSG_NOTIFICATION: LOG.error('Sent notification to %s >> %s' % |