mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-23 04:32:50 -04:00
Cleanup uPnP a bit
This commit is contained in:
parent
ccd9c33d98
commit
40fde5c892
@ -27,17 +27,18 @@ namespace MCGalaxy.Core {
|
||||
public sealed class UPnP {
|
||||
|
||||
public static bool CanUseUpnp { get { return Discover(); } }
|
||||
public static TimeSpan Timeout = TimeSpan.FromSeconds(3);
|
||||
|
||||
private const string req = "M-SEARCH * HTTP/1.1\r\n" +
|
||||
const string req =
|
||||
"M-SEARCH * HTTP/1.1\r\n" +
|
||||
"HOST: 239.255.255.250:1900\r\n" +
|
||||
"ST:upnp:rootdevice\r\n" +
|
||||
"MAN:\"ssdp:discover\"\r\n" +
|
||||
"MX:3\r\n\r\n";
|
||||
|
||||
static TimeSpan _timeout = new TimeSpan(0, 0, 0, 3);
|
||||
public static TimeSpan TimeOut { get { return _timeout; } set { _timeout = value; } }
|
||||
"MX:3\r\n" +
|
||||
"\r\n";
|
||||
|
||||
static string _serviceUrl;
|
||||
|
||||
private static bool Discover() {
|
||||
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
|
||||
s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
|
||||
@ -75,7 +76,7 @@ namespace MCGalaxy.Core {
|
||||
}
|
||||
}
|
||||
} while (length > 0);
|
||||
} while (start.Subtract(DateTime.UtcNow) < _timeout);
|
||||
} while (start.Subtract(DateTime.UtcNow) < Timeout);
|
||||
return false;
|
||||
}
|
||||
catch {
|
||||
@ -83,7 +84,7 @@ namespace MCGalaxy.Core {
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetServiceUrl(string resp) {
|
||||
static string GetServiceUrl(string resp) {
|
||||
#if !DEBUG
|
||||
try {
|
||||
#endif
|
||||
@ -98,83 +99,75 @@ namespace MCGalaxy.Core {
|
||||
XmlNode node = desc.SelectSingleNode("//tns:service[tns:serviceType=\"urn:schemas-upnp-org:service:WANIPConnection:1\"]/tns:controlURL/text()", nsMgr);
|
||||
if ( node == null )
|
||||
return null;
|
||||
XmlNode eventnode = desc.SelectSingleNode("//tns:service[tns:serviceType=\"urn:schemas-upnp-org:service:WANIPConnection:1\"]/tns:eventSubURL/text()", nsMgr);
|
||||
return CombineUrls(resp, node.Value);
|
||||
#if !DEBUG
|
||||
}
|
||||
catch { return null; }
|
||||
} catch { return null; }
|
||||
#endif
|
||||
}
|
||||
|
||||
private static string CombineUrls(string resp, string p) {
|
||||
static string CombineUrls(string resp, string p) {
|
||||
int n = resp.IndexOf("://");
|
||||
n = resp.IndexOf('/', n + 3);
|
||||
return resp.Substring(0, n) + p;
|
||||
}
|
||||
|
||||
public static void ForwardPort(int port, ProtocolType protocol, string description) {
|
||||
if ( string.IsNullOrEmpty(_serviceUrl) )
|
||||
if (String.IsNullOrEmpty(_serviceUrl) )
|
||||
throw new InvalidOperationException("No UPnP service available or Discover() has not been called");
|
||||
XmlDocument xdoc = SOAPRequest(_serviceUrl, "<u:AddPortMapping xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\">" +
|
||||
"<NewRemoteHost></NewRemoteHost><NewExternalPort>" + port.ToString() + "</NewExternalPort><NewProtocol>" + protocol.ToString().ToUpper() + "</NewProtocol>" +
|
||||
"<NewInternalPort>" + port.ToString() + "</NewInternalPort><NewInternalClient>" + GetLocalIP() +
|
||||
"</NewInternalClient><NewEnabled>1</NewEnabled><NewPortMappingDescription>" + description +
|
||||
"</NewPortMappingDescription><NewLeaseDuration>0</NewLeaseDuration></u:AddPortMapping>", "AddPortMapping");
|
||||
|
||||
XmlDocument xdoc = SOAPRequest(_serviceUrl,
|
||||
"<u:AddPortMapping xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\">" +
|
||||
"<NewRemoteHost></NewRemoteHost>" +
|
||||
"<NewExternalPort>" + port.ToString() + "</NewExternalPort>" +
|
||||
"<NewProtocol>" + protocol.ToString().ToUpper() + "</NewProtocol>" +
|
||||
"<NewInternalPort>" + port.ToString() + "</NewInternalPort>" +
|
||||
"<NewInternalClient>" + GetLocalIP() + "</NewInternalClient>" +
|
||||
"<NewEnabled>1</NewEnabled>" +
|
||||
"<NewPortMappingDescription>" + description + "</NewPortMappingDescription>" +
|
||||
"<NewLeaseDuration>0</NewLeaseDuration>" +
|
||||
"</u:AddPortMapping>", "AddPortMapping");
|
||||
}
|
||||
|
||||
public static void DeleteForwardingRule(int port, ProtocolType protocol) {
|
||||
if ( string.IsNullOrEmpty(_serviceUrl) )
|
||||
if (String.IsNullOrEmpty(_serviceUrl) )
|
||||
throw new InvalidOperationException("No UPnP service available or Discover() has not been called");
|
||||
|
||||
XmlDocument xdoc = SOAPRequest(_serviceUrl,
|
||||
"<u:DeletePortMapping xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\">" +
|
||||
"<NewRemoteHost>" +
|
||||
"</NewRemoteHost>" +
|
||||
"<NewRemoteHost>"</NewRemoteHost>" +
|
||||
"<NewExternalPort>" + port + "</NewExternalPort>" +
|
||||
"<NewProtocol>" + protocol.ToString().ToUpper() + "</NewProtocol>" +
|
||||
"</u:DeletePortMapping>", "DeletePortMapping");
|
||||
|
||||
}
|
||||
|
||||
[DebuggerStepThrough]
|
||||
public static IPAddress GetExternalIP() {
|
||||
if ( string.IsNullOrEmpty(_serviceUrl) )
|
||||
throw new InvalidOperationException("No UPnP service available or Discover() has not been called");
|
||||
XmlDocument xdoc = SOAPRequest(_serviceUrl, "<u:GetExternalIPAddress xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\">" +
|
||||
"</u:GetExternalIPAddress>", "GetExternalIPAddress");
|
||||
XmlNamespaceManager nsMgr = new XmlNamespaceManager(xdoc.NameTable);
|
||||
nsMgr.AddNamespace("tns", "urn:schemas-upnp-org:device-1-0");
|
||||
string IP = xdoc.SelectSingleNode("//NewExternalIPAddress/text()", nsMgr).Value;
|
||||
return IPAddress.Parse(IP);
|
||||
}
|
||||
|
||||
[DebuggerStepThrough]
|
||||
public static string GetLocalIP() {
|
||||
IPHostEntry host;
|
||||
string localIP = "?";
|
||||
host = Dns.GetHostEntry(Dns.GetHostName());
|
||||
foreach ( IPAddress ip in host.AddressList ) {
|
||||
if ( ip.AddressFamily == AddressFamily.InterNetwork ) {
|
||||
IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
|
||||
|
||||
foreach (IPAddress ip in host.AddressList) {
|
||||
if (ip.AddressFamily == AddressFamily.InterNetwork) {
|
||||
localIP = ip.ToString();
|
||||
}
|
||||
}
|
||||
return localIP;
|
||||
}
|
||||
|
||||
private static XmlDocument SOAPRequest(string url, string soap, string function) {
|
||||
|
||||
static XmlDocument SOAPRequest(string url, string soap, string function) {
|
||||
string req = "<?xml version=\"1.0\"?>" +
|
||||
"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" +
|
||||
"<s:Body>" +
|
||||
soap +
|
||||
"</s:Body>" +
|
||||
"<s:Body>" + soap + "</s:Body>" +
|
||||
"</s:Envelope>";
|
||||
|
||||
WebRequest r = HttpWebRequest.Create(url);
|
||||
r.Method = "POST";
|
||||
byte[] b = Encoding.UTF8.GetBytes(req);
|
||||
r.Headers.Add("SOAPACTION", "\"urn:schemas-upnp-org:service:WANIPConnection:1#" + function + "\"");
|
||||
r.ContentType = "text/xml; charset=\"utf-8\"";
|
||||
|
||||
byte[] b = Encoding.UTF8.GetBytes(req);
|
||||
r.ContentLength = b.Length;
|
||||
r.GetRequestStream().Write(b, 0, b.Length);
|
||||
|
||||
XmlDocument resp = new XmlDocument();
|
||||
WebResponse wres = r.GetResponse();
|
||||
Stream ress = wres.GetResponseStream();
|
||||
|
Loading…
x
Reference in New Issue
Block a user