/// <summary> /// Resolves local IP to public IP using STUN. /// </summary> /// <param name="stunServer">STUN server.</param> /// <param name="port">STUN server port. Default port is 3478.</param> /// <param name="localIP">Local IP address.</param> /// <returns>Returns public IP address.</returns> /// <exception cref="ArgumentNullException">Is raised when <b>stunServer</b> or <b>localIP</b> is null reference.</exception> /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception> /// <exception cref="IOException">Is raised when no connection to STUN server.</exception> public static IPAddress GetPublicIP(string stunServer, int port, IPAddress localIP) { if (stunServer == null) { throw new ArgumentNullException("stunServer"); } if (stunServer == "") { throw new ArgumentException("Argument 'stunServer' value must be specified."); } if (port < 1) { throw new ArgumentException("Invalid argument 'port' value."); } if (localIP == null) { throw new ArgumentNullException("localIP"); } if (!Net_Utils.IsPrivateIP(localIP)) { return(localIP); } STUN_Result result = Query(stunServer, port, Net_Utils.CreateSocket(new IPEndPoint(localIP, 0), ProtocolType.Udp)); if (result.PublicEndPoint != null) { return(result.PublicEndPoint.Address); } else { throw new IOException("Failed to STUN public IP address. STUN server name is invalid or firewall blocks STUN."); } }
public static void InitSTUN() { socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); socket.Bind(new IPEndPoint(IPAddress.Any, 0)); STUN = STUN_Client.Query(StunServer, StunServerPort, socket); }
TransactionFunc test1ResponeFunc(STUN_Message test1response) { // UDP blocked. if (test1response == null) { result = new STUN_Result(STUN_NetType.UdpBlocked, null); stunFail(); return null; } else { test1ResponeMessage = test1response; // Test II STUN_Message test2 = new STUN_Message(); test2.Type = STUN_MessageType.BindingRequest; test2.ChangeRequest = new STUN_t_ChangeRequest(true, true); // No NAT. if (transaction.socket.LocalEndPoint.Equals(test1response.MappedAddress)) { return transactionRespone(test2, noNATResponeFunc); } // NAT else { return transactionRespone(test2, NATResponeFunc); } } }
TransactionFunc succeedRespone(STUN_Result pResult) { result = pResult; stunSucceed(); return null; }
TransactionFunc noNATResponeFunc(STUN_Message pRequest) { STUN_Result lResult; // Open Internet. if (pRequest != null) { lResult = new STUN_Result(STUN_NetType.OpenInternet, pRequest.MappedAddress); } // Symmetric UDP firewall. else { lResult = new STUN_Result(STUN_NetType.SymmetricUdpFirewall, pRequest.MappedAddress); } return succeedRespone(lResult); }
/// <summary> /// Initializes SIP stack. /// </summary> private void InitStack() { #region Init audio devices if (AudioOut.Devices.Length == 0) { MessageBox.Show("Calling not possible, there are no speakers in computer.", "Error:", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (AudioIn.Devices.Length == 0) { MessageBox.Show("Calling not possible, there is no microphone in computer.", "Error:", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } m_pAudioOutDevice = AudioOut.Devices[0]; m_pAudioInDevice = AudioIn.Devices[0]; m_pAudioCodecs = new Dictionary<int, AudioCodec>(); m_pAudioCodecs.Add(0, new PCMU()); m_pAudioCodecs.Add(8, new PCMA()); m_pPlayer = new WavePlayer(AudioOut.Devices[0]); #endregion #region Get NAT handling methods m_pUPnP = new UPnP_NAT_Client(); STUN_Result stunResult = new STUN_Result(STUN_NetType.UdpBlocked, null); try { stunResult = STUN_Client.Query(m_StunServer, 3478, new IPEndPoint(IPAddress.Any, 0)); } catch { } if (stunResult.NetType == STUN_NetType.Symmetric || stunResult.NetType == STUN_NetType.UdpBlocked) { ToolStripMenuItem item_stun = new ToolStripMenuItem("STUN (" + stunResult.NetType + ")"); item_stun.Name = "stun"; item_stun.Enabled = false; ((ToolStripDropDownButton)m_pToolbar.Items["nat"]).DropDownItems.Add(item_stun); } else { ToolStripMenuItem item_stun = new ToolStripMenuItem("STUN (" + stunResult.NetType + ")"); item_stun.Name = "stun"; ((ToolStripDropDownButton)m_pToolbar.Items["nat"]).DropDownItems.Add(item_stun); } if (m_pUPnP.IsSupported) { ToolStripMenuItem item_upnp = new ToolStripMenuItem("UPnP"); item_upnp.Name = "upnp"; ((ToolStripDropDownButton)m_pToolbar.Items["nat"]).DropDownItems.Add(item_upnp); } else { ToolStripMenuItem item_upnp = new ToolStripMenuItem("UPnP Not Supported"); item_upnp.Name = "upnp"; item_upnp.Enabled = false; ((ToolStripDropDownButton)m_pToolbar.Items["nat"]).DropDownItems.Add(item_upnp); } //if(!((ToolStripDropDownButton)m_pToolbar.Items["nat"]).DropDownItems["stun"].Enabled && !((ToolStripDropDownButton)m_pToolbar.Items["nat"]).DropDownItems["upnp"].Enabled){ //MessageBox.Show("Calling may not possible, your firewall or router blocks STUN and doesn't support UPnP.\r\n\r\nSTUN Net Type: " + stunResult.NetType + "\r\n\r\nUPnP Supported: " + m_pUPnP.IsSupported,"Error:",MessageBoxButtons.OK,MessageBoxIcon.Error); //} ToolStripMenuItem item_no_nat = new ToolStripMenuItem("No NAT handling"); item_no_nat.Name = "no_nat"; ((ToolStripDropDownButton)m_pToolbar.Items["nat"]).DropDownItems.Add(item_no_nat); // Select first enabled item. foreach (ToolStripItem it in ((ToolStripDropDownButton)m_pToolbar.Items["nat"]).DropDownItems) { if (it.Enabled) { ((ToolStripMenuItem)it).Checked = true; m_NatHandlingType = it.Name; break; } } #endregion m_pStack = new SIP_Stack(); m_pStack.UserAgent = "GSDR"; m_pStack.BindInfo = new IPBindInfo[] { new IPBindInfo("", BindInfoProtocol.UDP, IPAddress.Any, m_SipPort) }; //m_pStack.Allow m_pStack.Error += new EventHandler<ExceptionEventArgs>(m_pStack_Error); m_pStack.RequestReceived += new EventHandler<SIP_RequestReceivedEventArgs>(m_pStack_RequestReceived); m_pStack.Start(); if (m_IsDebug) { wfrm_SIP_Debug debug = new wfrm_SIP_Debug(m_pStack); debug.Show(); } }