private void Listen() { try { byte[] buffer = null; logger.Debug("SIPUDPChannel socket on 0.0.0.0:" + m_localSIPEndPoint.GetIPEndPoint().Port + " listening started."); while (!Closed) { IPEndPoint inEndPoint = new IPEndPoint(IPAddress.Any, 0); //logger.Debug("SIPUDPChannel socket start.Receive."); try { buffer = m_sipConn.Receive(ref inEndPoint); } catch (SocketException sockex) { // ToDo. Pretty sure these exceptions get thrown when an ICMP message comes back indicating there is no listening // socket on the other end. It would be nice to be able to relate that back to the socket that the data was sent to // so that we know to stop sending. //logger.Warn("SocketException SIPUDPChannel Receive (" + sockExcp.ErrorCode + "). " + sockExcp.Message); //inEndPoint = new SIPEndPoint(new IPEndPoint(IPAddress.Any, 0)); logger.Error("SocketException listening on SIPUDPChannel. " + sockex.Message); continue; } catch (Exception listenExcp) { // There is no point logging this as without processing the ICMP message it's not possible to know which socket the rejection came from. logger.Error("Exception listening on SIPUDPChannel. " + listenExcp.Message); inEndPoint = new IPEndPoint(IPAddress.Any, 0); continue; } //logger.Debug("SIPUDPChannel socket end.Receive."); if (buffer == null || buffer.Length == 0) { // No need to care about zero byte packets. //string remoteEndPoint = (inEndPoint != null) ? inEndPoint.ToString() : "could not determine"; //logger.Error("Zero bytes received on SIPUDPChannel " + m_localSIPEndPoint.ToString() + "."); } else { SIPMessageReceived?.Invoke(this, new SIPEndPoint(SIPProtocolsEnum.udp, inEndPoint), buffer); } //logger.Debug("SIPUDPChannel socket message handled."); } logger.Debug("SIPUDPChannel socket on " + m_localSIPEndPoint + " listening halted."); } catch (Exception excp) { logger.Error("Exception SIPUDPChannel Listen. " + excp.Message); //throw excp; } }
private void EndReceiveMessageFrom(IAsyncResult ar) { EndPoint remoteEP = (ListeningIPAddress.AddressFamily == AddressFamily.InterNetwork) ? new IPEndPoint(IPAddress.Any, 0) : new IPEndPoint(IPAddress.IPv6Any, 0); try { if (!Closed) { SocketFlags flags = SocketFlags.None; int bytesRead = m_udpSocket.EndReceiveMessageFrom(ar, ref flags, ref remoteEP, out var packetInfo); if (bytesRead > 0) { SIPEndPoint remoteEndPoint = new SIPEndPoint(SIPProtocolsEnum.udp, remoteEP as IPEndPoint, ID, null); SIPEndPoint localEndPoint = new SIPEndPoint(SIPProtocolsEnum.udp, new IPEndPoint(packetInfo.Address, Port), ID, null); byte[] sipMsgBuffer = new byte[bytesRead]; Buffer.BlockCopy(m_recvBuffer, 0, sipMsgBuffer, 0, bytesRead); SIPMessageReceived?.Invoke(this, localEndPoint, remoteEndPoint, sipMsgBuffer); } } } catch (SocketException sockExcp) { // This exception can occur as the result of a Send operation. It's caused by an ICMP packet from a remote host // rejecting an incoming UDP packet. If that happens we want to stop further sends to the socket for a short period. Logger.Logger.Warn( $"SocketException SIPUDPChannel EndReceiveMessageFrom from {remoteEP} ({sockExcp.ErrorCode}). {sockExcp.Message}"); if (remoteEP != null) { m_sendFailures.TryAdd(remoteEP as IPEndPoint, DateTime.Now); } } catch (ObjectDisposedException) // Thrown when socket is closed. Can be safely ignored. { } catch (Exception excp) { Logger.Logger.Error($"Exception SIPUDPChannel EndReceiveMessageFrom. ->{excp.Message}"); } finally { if (!Closed) { Receive(); } } }
private void SIPTCPMessageReceived(SIPChannel channel, SIPEndPoint remoteEndPoint, byte[] buffer) { if (m_connectionFailures.ContainsKey(remoteEndPoint.GetIPEndPoint().ToString())) { m_connectionFailures.Remove(remoteEndPoint.GetIPEndPoint().ToString()); } if (m_connectionFailureStrikes.ContainsKey(remoteEndPoint.GetIPEndPoint().ToString())) { m_connectionFailureStrikes.Remove(remoteEndPoint.GetIPEndPoint().ToString()); } SIPMessageReceived?.Invoke(channel, remoteEndPoint, buffer); }
private async Task Listen() { logger.LogDebug("SIPUDPChannel socket on " + m_localSIPEndPoint.ToString() + " listening started."); while (!Closed) { try { var receiveResult = await m_sipConn.ReceiveAsync(); if (receiveResult.Buffer != null && receiveResult.Buffer.Length > 0) { SIPMessageReceived?.Invoke(this, new SIPEndPoint(SIPProtocolsEnum.udp, receiveResult.RemoteEndPoint), receiveResult.Buffer); } } catch (ObjectDisposedException) { // it's ok to be here after invoking Close() break; } catch (SocketException) { // ToDo. Pretty sure these exceptions get thrown when an ICMP message comes back indicating there is no listening // socket on the other end. It would be nice to be able to relate that back to the socket that the data was sent to // so that we know to stop sending. //logger.LogWarning("SocketException SIPUDPChannel Receive (" + sockExcp.ErrorCode + "). " + sockExcp.Message); //inEndPoint = new SIPEndPoint(new IPEndPoint(IPAddress.Any, 0)); continue; } catch (Exception listenExcp) { logger.LogError("Exception listening on SIPUDPChannel. " + listenExcp.Message); continue; } } logger.LogDebug("SIPUDPChannel socket on " + m_localSIPEndPoint + " listening halted."); }
private void EndReceiveMessageFrom(IAsyncResult ar) { try { SocketFlags flags = SocketFlags.None; EndPoint remoteEP = (ListeningIPAddress.AddressFamily == AddressFamily.InterNetwork) ? new IPEndPoint(IPAddress.Any, 0) : new IPEndPoint(IPAddress.IPv6Any, 0); int bytesRead = m_udpSocket.EndReceiveMessageFrom(ar, ref flags, ref remoteEP, out var packetInfo); if (bytesRead > 0) { SIPEndPoint remoteEndPoint = new SIPEndPoint(SIPProtocolsEnum.udp, remoteEP as IPEndPoint, ID, null); SIPEndPoint localEndPoint = new SIPEndPoint(SIPProtocolsEnum.udp, new IPEndPoint(packetInfo.Address, Port), ID, null); byte[] sipMsgBuffer = new byte[bytesRead]; Buffer.BlockCopy(m_recvBuffer, 0, sipMsgBuffer, 0, bytesRead); SIPMessageReceived?.Invoke(this, localEndPoint, remoteEndPoint, sipMsgBuffer); } } catch (SocketException sockExcp) { // ToDo. Pretty sure these exceptions get thrown when an ICMP message comes back indicating there is no listening // socket on the other end. It would be nice to be able to relate that back to the socket that the data was sent to // so that we know to stop sending. logger.LogWarning($"SocketException SIPUDPChannel Receive ({sockExcp.ErrorCode}). {sockExcp.Message}"); } catch (ObjectDisposedException) { } // Thrown when socket is closed. Can be safely ignored. catch (Exception excp) { logger.LogError($"Exception SIPUDPChannel.EndReceiveMessageFrom. {excp.Message}"); } finally { if (!Closed) { Receive(); } } }
private void SIPTLSMessageReceived(SIPChannel channel, SIPEndPoint remoteEndPoint, byte[] buffer) { SIPMessageReceived?.Invoke(channel, remoteEndPoint, buffer); }
/// <summary> /// Use to cause a mock message to be passed through to the SIP Transport class monitoring this mock channel. /// </summary> public void FireMessageReceived(SIPEndPoint localEndPoint, SIPEndPoint remoteEndPoint, byte[] sipMsgBuffer) { SIPMessageReceived.Invoke(this, localEndPoint, remoteEndPoint, sipMsgBuffer); }
/// <summary> /// Gets fired when a suspected SIP message is extracted from the TCP data stream. /// </summary> protected Task SIPTCPMessageReceived(SIPChannel channel, SIPEndPoint localEndPoint, SIPEndPoint remoteEndPoint, byte[] buffer) { return(SIPMessageReceived?.Invoke(channel, localEndPoint, remoteEndPoint, buffer)); }
/// <summary> /// Gets fired when a suspected SIP message is extracted from the TCP data stream. /// </summary> protected void SIPTCPMessageReceived(SIPChannel channel, SIPEndPoint localEndPoint, SIPEndPoint remoteEndPoint, byte[] buffer) { SIPMessageReceived?.Invoke(channel, localEndPoint, remoteEndPoint, buffer); }
private void EndReceiveFrom(IAsyncResult ar) { EndPoint remoteEP = (ListeningIPAddress.AddressFamily == AddressFamily.InterNetwork) ? new IPEndPoint(IPAddress.Any, 0) : new IPEndPoint(IPAddress.IPv6Any, 0); try { if (!Closed) { SocketFlags flags = SocketFlags.None; int bytesRead = m_udpSocket.EndReceiveFrom(ar, ref remoteEP); if (flags == SocketFlags.Truncated) { logger.LogWarning($"The message was too large to fit into the specified buffer and was truncated."); } if (bytesRead > 0) { // In addition to the note in the RTPChannel class about IPPacketInformation some versions of the mono runtime // on Android are unable to use Begin/EndReceiveMessageFrom. // See https://github.com/sipsorcery/sipsorcery/issues/302. // Those specific Begin/End calls were being used to get the packet information and identify which local // IP address a receive occurred on. Upon investigation it does not seem that the local IP address is // required on incoming SIP packets. The outgoing socket was previously chosen based on this address but // subsequent to https://github.com/sipsorcery/sipsorcery/issues/97 the mechanism has changed. // The calls have been changed to Begin/EndReceiveFrom in order to support Android. The consequence is the localEndPoint // parameter for the SIPMessageReceived will have an IP address of 0.0.0.0 or [::0] if wildcard addresses are in use. SIPEndPoint remoteEndPoint = new SIPEndPoint(SIPProtocolsEnum.udp, remoteEP as IPEndPoint, ID, null); //SIPEndPoint localEndPoint = new SIPEndPoint(SIPProtocolsEnum.udp, new IPEndPoint(packetInfo.Address, Port), ID, null); SIPEndPoint localEndPoint = new SIPEndPoint(SIPProtocolsEnum.udp, new IPEndPoint(ListeningIPAddress, Port), ID, null); byte[] sipMsgBuffer = new byte[bytesRead]; Buffer.BlockCopy(m_recvBuffer, 0, sipMsgBuffer, 0, bytesRead); SIPMessageReceived?.Invoke(this, localEndPoint, remoteEndPoint, sipMsgBuffer); } } } catch (SocketException sockExcp) { if (remoteEP != null) { // Note the SIPEndPoint is being used to take care of any IPv4 mapped to IPv6 addresses. SIPEndPoint remSIPEndPoint = new SIPEndPoint(SIPProtocolsEnum.udp, remoteEP as IPEndPoint); // This exception can occur as the result of a Send operation. It's caused by an ICMP packet from a remote host // rejecting an incoming UDP packet. If that happens we want to stop further sends to the socket for a short period. logger.LogWarning(sockExcp, $"SocketException SIPUDPChannel EndReceiveFrom from {remSIPEndPoint} ({sockExcp.ErrorCode}). {sockExcp.Message}"); m_sendFailures.TryAdd(remSIPEndPoint.GetIPEndPoint(), DateTime.Now); } else { logger.LogError($"SocketException SIPUDPChannel EndReceiveFrom. {sockExcp}"); } } catch (ObjectDisposedException) // Thrown when socket is closed. Can be safely ignored. { } catch (Exception excp) { logger.LogError($"Exception SIPUDPChannel EndReceiveFrom. {excp}"); } finally { if (!Closed) { Receive(); } } }