public static IPAddress GetPublicIPAddress(string stunServer) { try { logger.Debug("STUNClient attempting to determine public IP from " + stunServer + "."); using (UdpClient udpClient = new UdpClient(stunServer, m_defaultSTUNPort)) { STUNMessage initMessage = new STUNMessage(STUNMessageTypesEnum.BindingRequest); byte[] stunMessageBytes = initMessage.ToByteBuffer(); udpClient.Send(stunMessageBytes, stunMessageBytes.Length); IPAddress publicIPAddress = null; ManualResetEvent gotResponseMRE = new ManualResetEvent(false); udpClient.BeginReceive((ar) => { try { IPEndPoint stunResponseEndPoint = null; byte[] stunResponseBuffer = udpClient.EndReceive(ar, ref stunResponseEndPoint); if (stunResponseBuffer != null && stunResponseBuffer.Length > 0) { logger.Debug("STUNClient Response to initial STUN message received from " + stunResponseEndPoint + "."); STUNMessage stunResponse = STUNMessage.ParseSTUNMessage(stunResponseBuffer, stunResponseBuffer.Length); if (stunResponse.Attributes.Count > 0) { foreach (STUNAttribute stunAttribute in stunResponse.Attributes) { if (stunAttribute.AttributeType == STUNAttributeTypesEnum.MappedAddress) { publicIPAddress = ((STUNAddressAttribute)stunAttribute).Address; logger.Debug("STUNClient Public IP=" + publicIPAddress.ToString() + "."); } } } } gotResponseMRE.Set(); } catch (Exception recvExcp) { logger.Warn("Exception STUNClient Receive. " + recvExcp.Message); } }, null); if (gotResponseMRE.WaitOne(STUN_SERVER_RESPONSE_TIMEOUT * 1000)) { return(publicIPAddress); } else { logger.Warn("STUNClient server response timedout after " + STUN_SERVER_RESPONSE_TIMEOUT + "s."); return(null); } } } catch (Exception excp) { logger.Error("Exception STUNClient GetPublicIPAddress. " + excp.Message); return(null); //throw; } }
public void STUNPrimaryReceived(IPEndPoint localEndPoint, IPEndPoint receivedEndPoint, byte[] buffer, int bufferLength) { try { //Console.WriteLine("\n=> received from " + IPSocketAddress.GetSocketString(receivedEndPoint) + " on " + IPSocketAddress.GetSocketString(receivedOnEndPoint)); //Console.WriteLine(Utility.PrintBuffer(buffer)); STUNMessage stunRequest = STUNMessage.ParseSTUNMessage(buffer, bufferLength); //Console.WriteLine(stunRequest.ToString()); FireSTUNPrimaryRequestInTraceEvent(localEndPoint, receivedEndPoint, stunRequest); STUNMessage stunResponse = GetResponse(receivedEndPoint, stunRequest, true); byte[] stunResponseBuffer = stunResponse.ToByteBuffer(); bool changeAddress = false; bool changePort = false; foreach (STUNAttribute attr in stunRequest.Attributes) { if (attr.AttributeType == STUNAttributeTypesEnum.ChangeRequest) { STUNChangeRequestAttribute changeReqAttr = (STUNChangeRequestAttribute)attr; changeAddress = changeReqAttr.ChangeAddress; changePort = changeReqAttr.ChangePort; break; } } if (!changeAddress) { if (!changePort) { //Console.WriteLine("<= sending to " + IPSocketAddress.GetSocketString(receivedEndPoint) + " from " + IPSocketAddress.GetSocketString(m_primaryEndPoint)); m_primarySend(receivedEndPoint, stunResponseBuffer); FireSTUNPrimaryResponseOutTraceEvent(m_primaryEndPoint, receivedEndPoint, stunResponse); } else { //Console.WriteLine("<= sending to " + IPSocketAddress.GetSocketString(receivedEndPoint) + " from " + IPSocketAddress.GetSocketString(m_primaryDiffPortEndPoint)); m_primaryDiffPortSocket.Send(stunResponseBuffer, stunResponseBuffer.Length, receivedEndPoint); FireSTUNPrimaryResponseOutTraceEvent(m_primaryDiffPortEndPoint, receivedEndPoint, stunResponse); } } else { if (!changePort) { //Console.WriteLine("<= sending to " + IPSocketAddress.GetSocketString(receivedEndPoint) + " from " + IPSocketAddress.GetSocketString(m_secondaryEndPoint)); m_secondarySend(receivedEndPoint, stunResponseBuffer); FireSTUNSecondaryResponseOutTraceEvent(m_secondaryEndPoint, receivedEndPoint, stunResponse); } else { //Console.WriteLine("<= sending to " + IPSocketAddress.GetSocketString(receivedEndPoint) + " from " + IPSocketAddress.GetSocketString(m_secondaryDiffPortEndPoint)); m_secondaryDiffPortSocket.Send(stunResponseBuffer, stunResponseBuffer.Length, receivedEndPoint); FireSTUNSecondaryResponseOutTraceEvent(m_secondaryDiffPortEndPoint, receivedEndPoint, stunResponse); } } } catch (Exception excp) { logger.Debug("Exception STUNPrimaryReceived. " + excp.Message); } }