1 # Copyright (c) 2010, 2011, 2012 Nicira, Inc.
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at:
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
21 import ovs
.socket_util
27 from OpenSSL
import SSL
31 if sys
.platform
== 'win32':
32 import ovs
.winutils
as winutils
38 vlog
= ovs
.vlog
.Vlog("stream")
41 def stream_or_pstream_needs_probes(name
):
42 """ True if the stream or pstream specified by 'name' needs periodic probes
43 to verify connectivity. For [p]streams which need probes, it can take a
44 long time to notice the connection was dropped. Returns False if probes
45 aren't needed, and None if 'name' is invalid"""
47 cls
= Stream
._find
_method
(name
)
49 return cls
.needs_probes()
50 elif PassiveStream
.is_valid_name(name
):
51 return PassiveStream
.needs_probes(name
)
57 """Bidirectional byte stream. Unix domain sockets, tcp and ssl
65 # Kinds of events that one might wait for.
66 W_CONNECT
= 0 # Connect complete (success or failure).
67 W_RECV
= 1 # Data received.
68 W_SEND
= 2 # Send buffer room available.
72 _SSL_private_key_file
= None
73 _SSL_certificate_file
= None
74 _SSL_ca_cert_file
= None
77 _write
= None # overlapped for write operation
78 _read
= None # overlapped for read operation
79 _write_pending
= False
81 _retry_connect
= False
84 def register_method(method
, cls
):
85 Stream
._SOCKET
_METHODS
[method
+ ":"] = cls
88 def _find_method(name
):
89 for method
, cls
in six
.iteritems(Stream
._SOCKET
_METHODS
):
90 if name
.startswith(method
):
95 def is_valid_name(name
):
96 """Returns True if 'name' is a stream name in the form "TYPE:ARGS" and
97 TYPE is a supported stream type ("unix:", "tcp:" and "ssl:"),
99 return bool(Stream
._find
_method
(name
))
101 def __init__(self
, socket
, name
, status
, pipe
=None, is_server
=False):
104 if sys
.platform
== 'win32':
105 self
._read
= pywintypes
.OVERLAPPED()
106 self
._read
.hEvent
= winutils
.get_new_event()
107 self
._write
= pywintypes
.OVERLAPPED()
108 self
._write
.hEvent
= winutils
.get_new_event()
110 # Flag to check if fd is a server HANDLE. In the case of a
111 # server handle we have to issue a disconnect before closing
113 self
._server
= is_server
114 suffix
= name
.split(":", 1)[1]
115 suffix
= ovs
.util
.abs_file_name(ovs
.dirs
.RUNDIR
, suffix
)
116 self
._pipename
= winutils
.get_pipe_name(suffix
)
119 if status
== errno
.EAGAIN
:
120 self
.state
= Stream
.__S
_CONNECTING
122 self
.state
= Stream
.__S
_CONNECTED
124 self
.state
= Stream
.__S
_DISCONNECTED
128 # Default value of dscp bits for connection between controller and manager.
129 # Value of IPTOS_PREC_INTERNETCONTROL = 0xc0 which is defined
130 # in <netinet/ip.h> is used.
131 IPTOS_PREC_INTERNETCONTROL
= 0xc0
132 DSCP_DEFAULT
= IPTOS_PREC_INTERNETCONTROL
>> 2
135 def open(name
, dscp
=DSCP_DEFAULT
):
136 """Attempts to connect a stream to a remote peer. 'name' is a
137 connection name in the form "TYPE:ARGS", where TYPE is an active stream
138 class's name and ARGS are stream class-specific. The supported TYPEs
139 include "unix", "tcp", and "ssl".
141 Returns (error, stream): on success 'error' is 0 and 'stream' is the
142 new Stream, on failure 'error' is a positive errno value and 'stream'
145 Never returns errno.EAGAIN or errno.EINPROGRESS. Instead, returns 0
146 and a new Stream. The connect() method can be used to check for
147 successful connection completion."""
148 cls
= Stream
._find
_method
(name
)
150 return errno
.EAFNOSUPPORT
, None
152 suffix
= name
.split(":", 1)[1]
153 if name
.startswith("unix:"):
154 suffix
= ovs
.util
.abs_file_name(ovs
.dirs
.RUNDIR
, suffix
)
155 if sys
.platform
== 'win32':
156 pipename
= winutils
.get_pipe_name(suffix
)
158 if len(suffix
) > 255:
159 # Return invalid argument if the name is too long
160 return errno
.ENOENT
, None
163 # In case of "unix:" argument, the assumption is that
164 # there is a file created in the path (suffix).
165 open(suffix
, 'r').close()
167 return errno
.ENOENT
, None
170 npipe
= winutils
.create_file(pipename
)
172 winutils
.set_pipe_mode(npipe
,
173 win32pipe
.PIPE_READMODE_BYTE
)
174 except pywintypes
.error
as e
:
175 return errno
.ENOENT
, None
176 except pywintypes
.error
as e
:
177 if e
.winerror
== winutils
.winerror
.ERROR_PIPE_BUSY
:
178 # Pipe is busy, set the retry flag to true and retry
179 # again during the connect function.
180 Stream
.retry_connect
= True
181 return 0, cls(None, name
, errno
.EAGAIN
,
182 pipe
=win32file
.INVALID_HANDLE_VALUE
,
184 return errno
.ENOENT
, None
185 return 0, cls(None, name
, 0, pipe
=npipe
, is_server
=False)
187 error
, sock
= cls
._open
(suffix
, dscp
)
191 status
= ovs
.socket_util
.check_connection_completion(sock
)
192 return 0, cls(sock
, name
, status
)
195 def _open(suffix
, dscp
):
196 raise NotImplementedError("This method must be overrided by subclass")
199 def open_block(error_stream
):
200 """Blocks until a Stream completes its connection attempt, either
201 succeeding or failing. (error, stream) should be the tuple returned by
202 Stream.open(). Returns a tuple of the same form.
205 error, stream = Stream.open_block(Stream.open("unix:/tmp/socket"))"""
207 # Py3 doesn't support tuple parameter unpacking - PEP 3113
208 error
, stream
= error_stream
211 error
= stream
.connect()
212 if sys
.platform
== 'win32' and error
== errno
.WSAEWOULDBLOCK
:
213 # WSAEWOULDBLOCK would be the equivalent on Windows
214 # for EAGAIN on Unix.
216 if error
!= errno
.EAGAIN
:
219 poller
= ovs
.poller
.Poller()
220 stream
.run_wait(poller
)
221 stream
.connect_wait(poller
)
223 if stream
.socket
is not None:
224 assert error
!= errno
.EINPROGRESS
232 if self
.socket
is not None:
234 if self
.pipe
is not None:
236 # Flush the pipe to allow the client to read the pipe
237 # before disconnecting.
238 win32pipe
.FlushFileBuffers(self
.pipe
)
239 win32pipe
.DisconnectNamedPipe(self
.pipe
)
240 winutils
.close_handle(self
.pipe
, vlog
.warn
)
241 winutils
.close_handle(self
._read
.hEvent
, vlog
.warn
)
242 winutils
.close_handle(self
._write
.hEvent
, vlog
.warn
)
244 def __scs_connecting(self
):
245 if self
.socket
is not None:
246 retval
= ovs
.socket_util
.check_connection_completion(self
.socket
)
247 assert retval
!= errno
.EINPROGRESS
248 elif sys
.platform
== 'win32':
249 if self
.retry_connect
:
251 self
.pipe
= winutils
.create_file(self
._pipename
)
252 self
._retry
_connect
= False
254 except pywintypes
.error
as e
:
255 if e
.winerror
== winutils
.winerror
.ERROR_PIPE_BUSY
:
256 retval
= errno
.EAGAIN
258 self
._retry
_connect
= False
259 retval
= errno
.ENOENT
261 # If retry_connect is false, it means it's already
262 # connected so we can set the value of retval to 0
266 self
.state
= Stream
.__S
_CONNECTED
267 elif retval
!= errno
.EAGAIN
:
268 self
.state
= Stream
.__S
_DISCONNECTED
272 """Tries to complete the connection on this stream. If the connection
273 is complete, returns 0 if the connection was successful or a positive
274 errno value if it failed. If the connection is still in progress,
275 returns errno.EAGAIN."""
277 if self
.state
== Stream
.__S
_CONNECTING
:
278 self
.__scs
_connecting
()
280 if self
.state
== Stream
.__S
_CONNECTING
:
282 elif self
.state
== Stream
.__S
_CONNECTED
:
285 assert self
.state
== Stream
.__S
_DISCONNECTED
289 """Tries to receive up to 'n' bytes from this stream. Returns a
290 (error, string) tuple:
292 - If successful, 'error' is zero and 'string' contains between 1
293 and 'n' bytes of data.
295 - On error, 'error' is a positive errno value.
297 - If the connection has been closed in the normal fashion or if 'n'
298 is 0, the tuple is (0, "").
300 The recv function will not block waiting for data to arrive. If no
301 data have been received, it returns (errno.EAGAIN, "") immediately."""
303 retval
= self
.connect()
309 if sys
.platform
== 'win32' and self
.socket
is None:
310 return self
.__recv
_windows
(n
)
313 return (0, self
.socket
.recv(n
))
314 except socket
.error
as e
:
315 return (ovs
.socket_util
.get_exception_errno(e
), "")
317 def __recv_windows(self
, n
):
318 if self
._read
_pending
:
320 nBytesRead
= winutils
.get_overlapped_result(self
.pipe
,
323 self
._read
_pending
= False
324 recvBuffer
= self
._read
_buffer
[:nBytesRead
]
326 return (0, winutils
.get_decoded_buffer(recvBuffer
))
327 except pywintypes
.error
as e
:
328 if e
.winerror
== winutils
.winerror
.ERROR_IO_INCOMPLETE
:
329 # The operation is still pending, try again
330 self
._read
_pending
= True
331 return (errno
.EAGAIN
, "")
332 elif e
.winerror
in winutils
.pipe_disconnected_errors
:
333 # If the pipe was disconnected, return 0.
336 return (errno
.EINVAL
, "")
338 (errCode
, self
._read
_buffer
) = winutils
.read_file(self
.pipe
,
342 if errCode
== winutils
.winerror
.ERROR_IO_PENDING
:
343 self
._read
_pending
= True
344 return (errno
.EAGAIN
, "")
345 elif errCode
in winutils
.pipe_disconnected_errors
:
346 # If the pipe was disconnected, return 0.
352 nBytesRead
= winutils
.get_overlapped_result(self
.pipe
,
355 winutils
.win32event
.SetEvent(self
._read
.hEvent
)
356 except pywintypes
.error
as e
:
357 if e
.winerror
in winutils
.pipe_disconnected_errors
:
358 # If the pipe was disconnected, return 0.
361 return (e
.winerror
, "")
363 recvBuffer
= self
._read
_buffer
[:nBytesRead
]
364 return (0, winutils
.get_decoded_buffer(recvBuffer
))
367 """Tries to send 'buf' on this stream.
369 If successful, returns the number of bytes sent, between 1 and
370 len(buf). 0 is only a valid return value if len(buf) is 0.
372 On error, returns a negative errno value.
374 Will not block. If no bytes can be immediately accepted for
375 transmission, returns -errno.EAGAIN immediately."""
377 retval
= self
.connect()
383 if sys
.platform
== 'win32' and self
.socket
is None:
384 return self
.__send
_windows
(buf
)
387 # Python 3 has separate types for strings and bytes. We must have
389 if six
.PY3
and not isinstance(buf
, bytes
):
390 buf
= bytes(buf
, 'utf-8')
392 buf
= buf
.encode('utf-8')
393 return self
.socket
.send(buf
)
394 except socket
.error
as e
:
395 return -ovs
.socket_util
.get_exception_errno(e
)
397 def __send_windows(self
, buf
):
398 if self
._write
_pending
:
400 nBytesWritten
= winutils
.get_overlapped_result(self
.pipe
,
403 self
._write
_pending
= False
405 except pywintypes
.error
as e
:
406 if e
.winerror
== winutils
.winerror
.ERROR_IO_INCOMPLETE
:
407 # The operation is still pending, try again
408 self
._read
_pending
= True
410 elif e
.winerror
in winutils
.pipe_disconnected_errors
:
411 # If the pipe was disconnected, return connection reset.
412 return -errno
.ECONNRESET
416 buf
= winutils
.get_encoded_buffer(buf
)
417 self
._write
_pending
= False
418 (errCode
, nBytesWritten
) = winutils
.write_file(self
.pipe
,
422 if errCode
== winutils
.winerror
.ERROR_IO_PENDING
:
423 self
._write
_pending
= True
425 if (not nBytesWritten
and
426 errCode
in winutils
.pipe_disconnected_errors
):
427 # If the pipe was disconnected, return connection reset.
428 return -errno
.ECONNRESET
434 def run_wait(self
, poller
):
437 def wait(self
, poller
, wait
):
438 assert wait
in (Stream
.W_CONNECT
, Stream
.W_RECV
, Stream
.W_SEND
)
440 if self
.state
== Stream
.__S
_DISCONNECTED
:
441 poller
.immediate_wake()
444 if self
.state
== Stream
.__S
_CONNECTING
:
445 wait
= Stream
.W_CONNECT
447 if sys
.platform
== 'win32':
448 self
.__wait
_windows
(poller
, wait
)
451 if wait
== Stream
.W_RECV
:
452 poller
.fd_wait(self
.socket
, ovs
.poller
.POLLIN
)
454 poller
.fd_wait(self
.socket
, ovs
.poller
.POLLOUT
)
456 def __wait_windows(self
, poller
, wait
):
457 if self
.socket
is not None:
458 if wait
== Stream
.W_RECV
:
459 read_flags
= (win32file
.FD_READ |
460 win32file
.FD_ACCEPT |
463 win32file
.WSAEventSelect(self
.socket
,
466 except pywintypes
.error
as e
:
467 vlog
.err("failed to associate events with socket: %s"
469 poller
.fd_wait(self
._read
.hEvent
, ovs
.poller
.POLLIN
)
471 write_flags
= (win32file
.FD_WRITE |
472 win32file
.FD_CONNECT |
475 win32file
.WSAEventSelect(self
.socket
,
478 except pywintypes
.error
as e
:
479 vlog
.err("failed to associate events with socket: %s"
481 poller
.fd_wait(self
._write
.hEvent
, ovs
.poller
.POLLOUT
)
483 if wait
== Stream
.W_RECV
:
485 poller
.fd_wait(self
._read
.hEvent
, ovs
.poller
.POLLIN
)
486 elif wait
== Stream
.W_SEND
:
488 poller
.fd_wait(self
._write
.hEvent
, ovs
.poller
.POLLOUT
)
489 elif wait
== Stream
.W_CONNECT
:
492 def connect_wait(self
, poller
):
493 self
.wait(poller
, Stream
.W_CONNECT
)
495 def recv_wait(self
, poller
):
496 self
.wait(poller
, Stream
.W_RECV
)
498 def send_wait(self
, poller
):
499 if sys
.platform
== 'win32':
500 poller
.fd_wait(self
.connect
.hEvent
, ovs
.poller
.POLLIN
)
501 self
.wait(poller
, Stream
.W_SEND
)
504 # Don't delete the file: we might have forked.
505 if self
.socket
is not None:
507 if self
.pipe
is not None:
508 # Check if there are any remaining valid handles and close them
510 winutils
.close_handle(self
.pipe
)
511 if self
._read
.hEvent
:
512 winutils
.close_handle(self
._read
.hEvent
)
513 if self
._write
.hEvent
:
514 winutils
.close_handle(self
._write
.hEvent
)
517 def ssl_set_private_key_file(file_name
):
518 Stream
._SSL
_private
_key
_file
= file_name
521 def ssl_set_certificate_file(file_name
):
522 Stream
._SSL
_certificate
_file
= file_name
525 def ssl_set_ca_cert_file(file_name
):
526 Stream
._SSL
_ca
_cert
_file
= file_name
529 class PassiveStream(object):
531 connect
= None # overlapped for read operation
532 connect_pending
= False
535 def needs_probes(name
):
536 return False if name
.startswith("punix:") else True
539 def is_valid_name(name
):
540 """Returns True if 'name' is a passive stream name in the form
541 "TYPE:ARGS" and TYPE is a supported passive stream type (currently
542 "punix:" or "ptcp"), otherwise False."""
543 return name
.startswith("punix:") | name
.startswith("ptcp:")
545 def __init__(self
, sock
, name
, bind_path
, pipe
=None):
550 self
.connect
= pywintypes
.OVERLAPPED()
551 self
.connect
.hEvent
= winutils
.get_new_event(bManualReset
=True)
552 self
.connect_pending
= False
553 suffix
= name
.split(":", 1)[1]
554 suffix
= ovs
.util
.abs_file_name(ovs
.dirs
.RUNDIR
, suffix
)
555 self
._pipename
= winutils
.get_pipe_name(suffix
)
557 self
.bind_path
= bind_path
561 """Attempts to start listening for remote stream connections. 'name'
562 is a connection name in the form "TYPE:ARGS", where TYPE is an passive
563 stream class's name and ARGS are stream class-specific. Currently the
564 supported values for TYPE are "punix" and "ptcp".
566 Returns (error, pstream): on success 'error' is 0 and 'pstream' is the
567 new PassiveStream, on failure 'error' is a positive errno value and
568 'pstream' is None."""
569 if not PassiveStream
.is_valid_name(name
):
570 return errno
.EAFNOSUPPORT
, None
573 if name
.startswith("punix:"):
574 bind_path
= ovs
.util
.abs_file_name(ovs
.dirs
.RUNDIR
, bind_path
)
575 if sys
.platform
!= 'win32':
576 error
, sock
= ovs
.socket_util
.make_unix_socket(
577 socket
.SOCK_STREAM
, True, bind_path
, None)
581 # Branch used only on Windows
583 open(bind_path
, 'w').close()
585 return errno
.ENOENT
, None
587 pipename
= winutils
.get_pipe_name(bind_path
)
588 if len(pipename
) > 255:
589 # Return invalid argument if the name is too long
590 return errno
.ENOENT
, None
592 npipe
= winutils
.create_named_pipe(pipename
)
594 return errno
.ENOENT
, None
595 return 0, PassiveStream(None, name
, bind_path
, pipe
=npipe
)
597 elif name
.startswith("ptcp:"):
598 sock
= socket
.socket(socket
.AF_INET
, socket
.SOCK_STREAM
)
599 sock
.setsockopt(socket
.SOL_SOCKET
, socket
.SO_REUSEADDR
, 1)
600 remote
= name
.split(':')
601 sock
.bind((remote
[1], int(remote
[2])))
604 raise Exception('Unknown connection string')
608 except socket
.error
as e
:
609 vlog
.err("%s: listen: %s" % (name
, os
.strerror(e
.error
)))
613 return 0, PassiveStream(sock
, name
, bind_path
)
616 """Closes this PassiveStream."""
617 if self
.socket
is not None:
619 if self
.pipe
is not None:
620 winutils
.close_handle(self
.pipe
, vlog
.warn
)
621 winutils
.close_handle(self
.connect
.hEvent
, vlog
.warn
)
622 if self
.bind_path
is not None:
623 ovs
.fatal_signal
.unlink_file_now(self
.bind_path
)
624 self
.bind_path
= None
627 """Tries to accept a new connection on this passive stream. Returns
628 (error, stream): if successful, 'error' is 0 and 'stream' is the new
629 Stream object, and on failure 'error' is a positive errno value and
632 Will not block waiting for a connection. If no connection is ready to
633 be accepted, returns (errno.EAGAIN, None) immediately."""
634 if sys
.platform
== 'win32' and self
.socket
is None:
635 return self
.__accept
_windows
()
638 sock
, addr
= self
.socket
.accept()
639 ovs
.socket_util
.set_nonblocking(sock
)
640 if (sys
.platform
!= 'win32' and sock
.family
== socket
.AF_UNIX
):
641 return 0, Stream(sock
, "unix:%s" % addr
, 0)
642 return 0, Stream(sock
, 'ptcp:%s:%s' % (addr
[0],
644 except socket
.error
as e
:
645 error
= ovs
.socket_util
.get_exception_errno(e
)
646 if sys
.platform
== 'win32' and error
== errno
.WSAEWOULDBLOCK
:
647 # WSAEWOULDBLOCK would be the equivalent on Windows
648 # for EAGAIN on Unix.
650 if error
!= errno
.EAGAIN
:
652 vlog
.dbg("accept: %s" % os
.strerror(error
))
655 def __accept_windows(self
):
656 if self
.connect_pending
:
658 winutils
.get_overlapped_result(self
.pipe
, self
.connect
, False)
659 except pywintypes
.error
as e
:
660 if e
.winerror
== winutils
.winerror
.ERROR_IO_INCOMPLETE
:
661 # The operation is still pending, try again
662 self
.connect_pending
= True
663 return errno
.EAGAIN
, None
666 win32pipe
.DisconnectNamedPipe(self
.pipe
)
667 return errno
.EINVAL
, None
668 self
.connect_pending
= False
670 error
= winutils
.connect_named_pipe(self
.pipe
, self
.connect
)
672 if error
== winutils
.winerror
.ERROR_IO_PENDING
:
673 self
.connect_pending
= True
674 return errno
.EAGAIN
, None
675 elif error
!= winutils
.winerror
.ERROR_PIPE_CONNECTED
:
677 win32pipe
.DisconnectNamedPipe(self
.pipe
)
678 self
.connect_pending
= False
679 return errno
.EINVAL
, None
681 win32event
.SetEvent(self
.connect
.hEvent
)
683 npipe
= winutils
.create_named_pipe(self
._pipename
)
685 return errno
.ENOENT
, None
689 winutils
.win32event
.ResetEvent(self
.connect
.hEvent
)
690 return 0, Stream(None, self
.name
, 0, pipe
=old_pipe
)
692 def wait(self
, poller
):
693 if sys
.platform
!= 'win32' or self
.socket
is not None:
694 poller
.fd_wait(self
.socket
, ovs
.poller
.POLLIN
)
696 poller
.fd_wait(self
.connect
.hEvent
, ovs
.poller
.POLLIN
)
699 # Don't delete the file: we might have forked.
700 if self
.socket
is not None:
702 if self
.pipe
is not None:
703 # Check if there are any remaining valid handles and close them
705 winutils
.close_handle(self
.pipe
)
706 if self
._connect
.hEvent
:
707 winutils
.close_handle(self
._read
.hEvent
)
712 Active %s connection methods:
713 unix:FILE Unix domain socket named FILE
714 tcp:IP:PORT TCP socket to IP with port no of PORT
715 ssl:IP:PORT SSL socket to IP with port no of PORT
717 Passive %s connection methods:
718 punix:FILE Listen on Unix domain socket FILE""" % (name
, name
)
721 class UnixStream(Stream
):
727 def _open(suffix
, dscp
):
728 connect_path
= suffix
729 return ovs
.socket_util
.make_unix_socket(socket
.SOCK_STREAM
,
730 True, None, connect_path
)
733 Stream
.register_method("unix", UnixStream
)
736 class TCPStream(Stream
):
742 def _open(suffix
, dscp
):
743 error
, sock
= ovs
.socket_util
.inet_open_active(socket
.SOCK_STREAM
,
746 sock
.setsockopt(socket
.IPPROTO_TCP
, socket
.TCP_NODELAY
, 1)
750 Stream
.register_method("tcp", TCPStream
)
753 class SSLStream(Stream
):
759 def verify_cb(conn
, cert
, errnum
, depth
, ok
):
763 def _open(suffix
, dscp
):
764 error
, sock
= TCPStream
._open
(suffix
, dscp
)
768 # Create an SSL context
769 ctx
= SSL
.Context(SSL
.SSLv23_METHOD
)
770 ctx
.set_verify(SSL
.VERIFY_PEER
, SSLStream
.verify_cb
)
771 ctx
.set_options(SSL
.OP_NO_SSLv2 | SSL
.OP_NO_SSLv3
)
772 # If the client has not set the SSL configuration files
773 # exception would be raised.
774 ctx
.use_privatekey_file(Stream
._SSL
_private
_key
_file
)
775 ctx
.use_certificate_file(Stream
._SSL
_certificate
_file
)
776 ctx
.load_verify_locations(Stream
._SSL
_ca
_cert
_file
)
778 ssl_sock
= SSL
.Connection(ctx
, sock
)
779 ssl_sock
.set_connect_state()
780 return error
, ssl_sock
783 retval
= super(SSLStream
, self
).connect()
788 # TCP Connection is successful. Now do the SSL handshake
790 self
.socket
.do_handshake()
791 except SSL
.WantReadError
:
793 except SSL
.SysCallError
as e
:
794 return ovs
.socket_util
.get_exception_errno(e
)
800 return super(SSLStream
, self
).recv(n
)
801 except SSL
.WantReadError
:
802 return (errno
.EAGAIN
, "")
803 except SSL
.SysCallError
as e
:
804 return (ovs
.socket_util
.get_exception_errno(e
), "")
805 except SSL
.ZeroReturnError
:
810 if isinstance(buf
, six
.text_type
):
811 # Convert to byte stream if the buffer is string type/unicode.
812 # pyopenssl version 0.14 expects the buffer to be byte string.
813 buf
= buf
.encode('utf-8')
814 return super(SSLStream
, self
).send(buf
)
815 except SSL
.WantWriteError
:
817 except SSL
.SysCallError
as e
:
818 return -ovs
.socket_util
.get_exception_errno(e
)
822 # Register SSL only if the OpenSSL module is available
823 Stream
.register_method("ssl", SSLStream
)