Class: OverSIP::SIP::TlsClient
- Inherits:
-
TcpClient
- Object
- EM::Connection
- Connection
- TcpConnection
- TcpClient
- OverSIP::SIP::TlsClient
- Defined in:
- lib/oversip/sip/listeners/tls_client.rb
Direct Known Subclasses
Constant Summary collapse
- TLS_HANDSHAKE_MAX_TIME =
4
Constants inherited from TcpConnection
OverSIP::SIP::TcpConnection::HEADERS_MAX_SIZE
Constants included from MessageProcessor
Instance Attribute Summary collapse
-
#callback_on_server_tls_handshake ⇒ Object
writeonly
Sets the attribute callback_on_server_tls_handshake.
Attributes inherited from TcpClient
#connected, #pending_client_transactions
Attributes inherited from Connection
Instance Method Summary collapse
- #connection_completed ⇒ Object
-
#initialize(ip, port) ⇒ TlsClient
constructor
A new instance of TlsClient.
-
#send_sip_msg(msg, ip = nil, port = nil) ⇒ Object
In TLS client, we must wait until ssl_handshake_completed is completed before sending data.
-
#ssl_handshake_completed ⇒ Object
This is called after all the calls to ssl_verify_peer().
-
#ssl_verify_peer(pem) ⇒ Object
Called for every certificate provided by the peer.
- #unbind(cause = nil) ⇒ Object
Methods inherited from TcpClient
Methods inherited from TcpConnection
#get_body, #parse_headers, #process_received_data, #receive_data, #remote_ip, #remote_ip_type, #remote_port
Methods inherited from Connection
#open?, outbound_listener?, #receive_senderror, reliable_transport_listener?, #transport
Methods included from Logger
close, fg_system_msg2str, init_logger_mq, load_methods, #log_id, syslog_system_msg2str, syslog_user_msg2str
Constructor Details
#initialize(ip, port) ⇒ TlsClient
Returns a new instance of TlsClient.
11 12 13 14 |
# File 'lib/oversip/sip/listeners/tls_client.rb', line 11 def initialize ip, port super @pending_messages = [] end |
Instance Attribute Details
#callback_on_server_tls_handshake=(value) ⇒ Object (writeonly)
Sets the attribute callback_on_server_tls_handshake
8 9 10 |
# File 'lib/oversip/sip/listeners/tls_client.rb', line 8 def callback_on_server_tls_handshake=(value) @callback_on_server_tls_handshake = value end |
Instance Method Details
#connection_completed ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/oversip/sip/listeners/tls_client.rb', line 17 def connection_completed @server_pems = [] @server_last_pem = false start_tls({ :verify_peer => @callback_on_server_tls_handshake, :cert_chain_file => ::OverSIP.tls_public_cert, :private_key_file => ::OverSIP.tls_private_cert, :use_tls => true }) # If the remote server does never send us a TLS certificate # after the TCP connection we would leak by storing more and # more messages in @pending_messages array. @timer_tls_handshake = ::EM::Timer.new(TLS_HANDSHAKE_MAX_TIME) do unless @connected log_system_notice "TLS handshake not performed within #{TLS_HANDSHAKE_MAX_TIME} seconds, closing the connection" close_connection end end end |
#send_sip_msg(msg, ip = nil, port = nil) ⇒ Object
In TLS client, we must wait until ssl_handshake_completed is completed before sending data. If not, data will be sent in plain TCP.
http://dev.sipdoc.net/issues/457
108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/oversip/sip/listeners/tls_client.rb', line 108 def send_sip_msg msg, ip=nil, port=nil if self.error? log_system_notice "SIP message could not be sent, connection is closed" return false end if @connected send_data msg else log_system_debug "TLS handshake not completed yet, waiting before sending the message" if $oversip_debug @pending_messages << msg end true end |
#ssl_handshake_completed ⇒ Object
This is called after all the calls to ssl_verify_peer().
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/oversip/sip/listeners/tls_client.rb', line 57 def ssl_handshake_completed log_system_debug("TLS connection established to " << remote_desc) if $oversip_debug # @connected in TlsClient means "TLS connection" rather than # just "TCP connection". @connected = true @timer_tls_handshake.cancel if @timer_tls_handshake # Run OverSIP::SipEvents.on_server_tls_handshake. ::Fiber.new do if @callback_on_server_tls_handshake log_system_debug "running OverSIP::SipEvents.on_server_tls_handshake()..." if $oversip_debug begin ::OverSIP::SipEvents.on_server_tls_handshake self, @server_pems rescue ::Exception => e log_system_error "error calling OverSIP::SipEvents.on_server_tls_handshake():" log_system_error e close_connection end # If the user or peer has closed the connection in the on_server_tls_handshake() callback # then notify pending transactions. if @local_closed or error? log_system_debug "connection closed, aborting" if $oversip_debug @pending_client_transactions.each do |client_transaction| client_transaction.tls_validation_failed end @pending_client_transactions.clear @pending_messages.clear @state = :ignore end end @pending_client_transactions.clear @pending_messages.each do |msg| send_data msg end @pending_messages.clear end.resume end |
#ssl_verify_peer(pem) ⇒ Object
Called for every certificate provided by the peer. This is just called in case @callback_on_server_tls_handshake is true.
42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/oversip/sip/listeners/tls_client.rb', line 42 def ssl_verify_peer pem # TODO: Dirty workaround for bug https://github.com/eventmachine/eventmachine/issues/194. return true if @server_last_pem == pem @server_last_pem = pem @server_pems << pem log_system_debug "received certificate num #{@server_pems.size} from server" if $oversip_debug # Validation must be done in ssl_handshake_completed after receiving all the certs, so return true. return true end |
#unbind(cause = nil) ⇒ Object
98 99 100 101 102 |
# File 'lib/oversip/sip/listeners/tls_client.rb', line 98 def unbind cause=nil super @timer_tls_handshake.cancel if @timer_tls_handshake @pending_messages.clear end |