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 <[email protected]>
---
 ryu/services/protocols/bgp/speaker.py | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/ryu/services/protocols/bgp/speaker.py 
b/ryu/services/protocols/bgp/speaker.py
index d5a543a..e4a9bc9 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' %
-- 
1.8.5.2 (Apple Git-48)


------------------------------------------------------------------------------
HPCC Systems Open Source Big Data Platform from LexisNexis Risk Solutions
Find What Matters Most in Your Big Data with HPCC Systems
Open Source. Fast. Scalable. Simple. Ideal for Dirty Data.
Leverages Graph Analysis for Fast Processing & Easy Data Exploration
http://p.sf.net/sfu/hpccsystems
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to