summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2014-06-15 21:22:35 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2014-06-16 08:11:41 +0900
commitf513b8751ddde0274203b589057da40e82ac9275 (patch)
tree9d221bdd70f20893fffc1a60fd344537257bd76f
parent783663afb29ebd0abeaae7792d924b65bc72db14 (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.py13
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' %