/// <summary> /// Transfers the channel to a waiting connection. /// </summary> /// <returns>TRUE if the channel should be kept open; FALSE otherwise.</returns> public bool TransferListenerChannel( uint channelId, string serverUri, Uri endpointUrl) { bool accepted = false; TcpListenerChannel channel = null; lock (m_lock) { if (!m_channels.TryGetValue(channelId, out channel)) { throw ServiceResultException.Create(StatusCodes.BadTcpSecureChannelUnknown, "Could not find secure channel request."); } } // notify the application. if (ConnectionWaiting != null) { var args = new TcpConnectionWaitingEventArgs(serverUri, endpointUrl, channel.Socket); ConnectionWaiting(this, args); accepted = args.Accepted; } if (accepted) { lock (m_lock) { // remove it so it does not get cleaned up as an inactive connection. m_channels.Remove(channelId); } } return(accepted); }
/// <summary> /// Handles requests arriving from a channel. /// </summary> private void OnRequestReceived(TcpListenerChannel channel, uint requestId, IServiceRequest request) { try { if (m_callback != null) { IAsyncResult result = m_callback.BeginProcessRequest( channel.GlobalChannelId, channel.EndpointDescription, request, OnProcessRequestComplete, new object[] { channel, requestId, request }); } } catch (Exception e) { Utils.Trace(e, "TCPLISTENER - Unexpected error processing request."); } }
/// <summary> /// Binds a new socket to an existing channel. /// </summary> public bool ReconnectToExistingChannel( IMessageSocket socket, uint requestId, uint sequenceNumber, uint channelId, X509Certificate2 clientCertificate, ChannelToken token, OpenSecureChannelRequest request) { TcpListenerChannel channel = null; lock (m_lock) { if (!m_channels.TryGetValue(channelId, out channel)) { throw ServiceResultException.Create(StatusCodes.BadTcpSecureChannelUnknown, "Could not find secure channel referenced in the OpenSecureChannel request."); } } channel.Reconnect(socket, requestId, sequenceNumber, clientCertificate, token, request); Utils.Trace("Channel {0} reconnected", channelId); return(true); }
/// <summary> /// Handles a new connection. /// </summary> private void OnAccept(object sender, SocketAsyncEventArgs e) { TcpListenerChannel channel = null; bool repeatAccept = false; do { repeatAccept = false; lock (m_lock) { Socket listeningSocket = e.UserToken as Socket; if (listeningSocket == null) { Utils.Trace("OnAccept: Listensocket was null."); e.Dispose(); return; } // check if the accept socket has been created. if (e.AcceptSocket != null && e.SocketError == SocketError.Success) { try { if (m_reverseConnectListener) { // create the channel to manage incoming reverse connections. channel = new TcpReverseConnectChannel( m_listenerId, this, m_bufferManager, m_quotas, m_descriptions); } else { // create the channel to manage incoming connections. channel = new TcpServerChannel( m_listenerId, this, m_bufferManager, m_quotas, m_serverCertificate, m_serverCertificateChain, m_descriptions); } if (m_callback != null) { channel.SetRequestReceivedCallback(new TcpChannelRequestEventHandler(OnRequestReceived)); } // get channel id uint channelId = GetNextChannelId(); // start accepting messages on the channel. channel.Attach(channelId, e.AcceptSocket); // save the channel for shutdown and reconnects. m_channels.Add(channelId, channel); } catch (Exception ex) { Utils.Trace(ex, "Unexpected error accepting a new connection."); } } e.Dispose(); if (e.SocketError != SocketError.OperationAborted) { // go back and wait for the next connection. try { e = new SocketAsyncEventArgs(); e.Completed += OnAccept; e.UserToken = listeningSocket; if (!listeningSocket.AcceptAsync(e)) { repeatAccept = true; } } catch (Exception ex) { Utils.Trace(ex, "Unexpected error listening for a new connection."); } } } } while (repeatAccept); }