public void Connect()
    {
        clients.Clear();
        lastContactWithClient.Clear();
        clientGuids.Clear();
        toDos.Clear();

        IPEndPoint stunEndPoint = new IPEndPoint(IPAddress.Any, 0);

        foreach (IPAddress ip in Dns.GetHostAddresses("stun3.l.google.com"))
        {
            if (ip.AddressFamily == AddressFamily.InterNetwork)
            {
                stunEndPoint = new IPEndPoint(ip, 19302);
            }
        }

        if (stunEndPoint.Address == IPAddress.Any)
        {
            throw new Exception("STUN failed");
        }

        socket.Bind(new IPEndPoint(IPAddress.Any, port));
        Debug.Log("[Server][" + DateTime.Now + "] START " + socket.LocalEndPoint);

        STUNQueryResult queryResult = STUNClient.Query(socket, stunEndPoint, STUNQueryType.PublicIP);

        publicEndPoint = queryResult.PublicEndPoint;

        Debug.Log("[Server][" + DateTime.Now + "] STUN " + publicEndPoint + " via STUN server " + stunEndPoint);
    }
Beispiel #2
0
        static P2pEndPoint GetExternalEndPoint(Socket socket)
        {
            // https://gist.github.com/zziuni/3741933

            List <Tuple <string, int> > stunServers = new List <Tuple <string, int> >();

            stunServers.Add(new Tuple <string, int>("stun.l.google.com", 19302));
            stunServers.Add(new Tuple <string, int>("iphone-stun.strato-iphone.de", 3478));
            stunServers.Add(new Tuple <string, int>("numb.viagenie.ca", 3478));
            stunServers.Add(new Tuple <string, int>("s1.taraba.net", 3478));
            stunServers.Add(new Tuple <string, int>("s2.taraba.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.12connect.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.12voip.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.1und1.de", 3478));
            stunServers.Add(new Tuple <string, int>("stun.2talk.co.nz", 3478));
            stunServers.Add(new Tuple <string, int>("stun.2talk.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.3clogic.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.3cx.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.a-mm.tv", 3478));
            stunServers.Add(new Tuple <string, int>("stun.aa.net.uk", 3478));
            stunServers.Add(new Tuple <string, int>("stun.acrobits.cz", 3478));
            stunServers.Add(new Tuple <string, int>("stun.actionvoip.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.advfn.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.aeta-audio.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.aeta.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.alltel.com.au", 3478));
            stunServers.Add(new Tuple <string, int>("stun.altar.com.pl", 3478));
            stunServers.Add(new Tuple <string, int>("stun.annatel.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.antisip.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.arbuz.ru", 3478));
            stunServers.Add(new Tuple <string, int>("stun.avigora.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.avigora.fr", 3478));
            stunServers.Add(new Tuple <string, int>("stun.awa-shima.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.awt.be", 3478));
            stunServers.Add(new Tuple <string, int>("stun.b2b2c.ca", 3478));
            stunServers.Add(new Tuple <string, int>("stun.bahnhof.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.barracuda.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.bluesip.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.bmwgs.cz", 3478));
            stunServers.Add(new Tuple <string, int>("stun.botonakis.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.budgetphone.nl", 3478));
            stunServers.Add(new Tuple <string, int>("stun.budgetsip.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.cablenet-as.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.callromania.ro", 3478));
            stunServers.Add(new Tuple <string, int>("stun.callwithus.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.cbsys.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.chathelp.ru", 3478));
            stunServers.Add(new Tuple <string, int>("stun.cheapvoip.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.ciktel.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.cloopen.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.colouredlines.com.au", 3478));
            stunServers.Add(new Tuple <string, int>("stun.comfi.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.commpeak.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.comtube.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.comtube.ru", 3478));
            stunServers.Add(new Tuple <string, int>("stun.cope.es", 3478));
            stunServers.Add(new Tuple <string, int>("stun.counterpath.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.counterpath.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.cryptonit.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.darioflaccovio.it", 3478));
            stunServers.Add(new Tuple <string, int>("stun.datamanagement.it", 3478));
            stunServers.Add(new Tuple <string, int>("stun.dcalling.de", 3478));
            stunServers.Add(new Tuple <string, int>("stun.decanet.fr", 3478));
            stunServers.Add(new Tuple <string, int>("stun.demos.ru", 3478));
            stunServers.Add(new Tuple <string, int>("stun.develz.org", 3478));
            stunServers.Add(new Tuple <string, int>("stun.dingaling.ca", 3478));
            stunServers.Add(new Tuple <string, int>("stun.doublerobotics.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.drogon.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.duocom.es", 3478));
            stunServers.Add(new Tuple <string, int>("stun.dus.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.e-fon.ch", 3478));
            stunServers.Add(new Tuple <string, int>("stun.easybell.de", 3478));
            stunServers.Add(new Tuple <string, int>("stun.easycall.pl", 3478));
            stunServers.Add(new Tuple <string, int>("stun.easyvoip.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.efficace-factory.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.einsundeins.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.einsundeins.de", 3478));
            stunServers.Add(new Tuple <string, int>("stun.ekiga.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.epygi.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.etoilediese.fr", 3478));
            stunServers.Add(new Tuple <string, int>("stun.eyeball.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.faktortel.com.au", 3478));
            stunServers.Add(new Tuple <string, int>("stun.freecall.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.freeswitch.org", 3478));
            stunServers.Add(new Tuple <string, int>("stun.freevoipdeal.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.fuzemeeting.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.gmx.de", 3478));
            stunServers.Add(new Tuple <string, int>("stun.gmx.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.gradwell.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.halonet.pl", 3478));
            stunServers.Add(new Tuple <string, int>("stun.hellonanu.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.hoiio.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.hosteurope.de", 3478));
            stunServers.Add(new Tuple <string, int>("stun.ideasip.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.imesh.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.infra.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.internetcalls.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.intervoip.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.ipcomms.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.ipfire.org", 3478));
            stunServers.Add(new Tuple <string, int>("stun.ippi.fr", 3478));
            stunServers.Add(new Tuple <string, int>("stun.ipshka.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.iptel.org", 3478));
            stunServers.Add(new Tuple <string, int>("stun.irian.at", 3478));
            stunServers.Add(new Tuple <string, int>("stun.it1.hr", 3478));
            stunServers.Add(new Tuple <string, int>("stun.ivao.aero", 3478));
            stunServers.Add(new Tuple <string, int>("stun.jappix.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.jumblo.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.justvoip.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.kanet.ru", 3478));
            stunServers.Add(new Tuple <string, int>("stun.kiwilink.co.nz", 3478));
            stunServers.Add(new Tuple <string, int>("stun.kundenserver.de", 3478));
            stunServers.Add(new Tuple <string, int>("stun.linea7.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.linphone.org", 3478));
            stunServers.Add(new Tuple <string, int>("stun.liveo.fr", 3478));
            stunServers.Add(new Tuple <string, int>("stun.lowratevoip.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.lugosoft.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.lundimatin.fr", 3478));
            stunServers.Add(new Tuple <string, int>("stun.magnet.ie", 3478));
            stunServers.Add(new Tuple <string, int>("stun.manle.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.mgn.ru", 3478));
            stunServers.Add(new Tuple <string, int>("stun.mit.de", 3478));
            stunServers.Add(new Tuple <string, int>("stun.mitake.com.tw", 3478));
            stunServers.Add(new Tuple <string, int>("stun.miwifi.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.modulus.gr", 3478));
            stunServers.Add(new Tuple <string, int>("stun.mozcom.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.myvoiptraffic.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.mywatson.it", 3478));
            stunServers.Add(new Tuple <string, int>("stun.nas.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.neotel.co.za", 3478));
            stunServers.Add(new Tuple <string, int>("stun.netappel.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.netappel.fr", 3478));
            stunServers.Add(new Tuple <string, int>("stun.netgsm.com.tr", 3478));
            stunServers.Add(new Tuple <string, int>("stun.nfon.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.noblogs.org", 3478));
            stunServers.Add(new Tuple <string, int>("stun.noc.ams-ix.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.node4.co.uk", 3478));
            stunServers.Add(new Tuple <string, int>("stun.nonoh.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.nottingham.ac.uk", 3478));
            stunServers.Add(new Tuple <string, int>("stun.nova.is", 3478));
            stunServers.Add(new Tuple <string, int>("stun.nventure.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.on.net.mk", 3478));
            stunServers.Add(new Tuple <string, int>("stun.ooma.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.ooonet.ru", 3478));
            stunServers.Add(new Tuple <string, int>("stun.oriontelekom.rs", 3478));
            stunServers.Add(new Tuple <string, int>("stun.outland-net.de", 3478));
            stunServers.Add(new Tuple <string, int>("stun.ozekiphone.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.patlive.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.personal-voip.de", 3478));
            stunServers.Add(new Tuple <string, int>("stun.petcube.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.phone.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.phoneserve.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.pjsip.org", 3478));
            stunServers.Add(new Tuple <string, int>("stun.poivy.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.powerpbx.org", 3478));
            stunServers.Add(new Tuple <string, int>("stun.powervoip.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.ppdi.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.prizee.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.qq.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.qvod.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.rackco.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.rapidnet.de", 3478));
            stunServers.Add(new Tuple <string, int>("stun.rb-net.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.refint.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.remote-learner.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.rixtelecom.se", 3478));
            stunServers.Add(new Tuple <string, int>("stun.rockenstein.de", 3478));
            stunServers.Add(new Tuple <string, int>("stun.rolmail.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.rounds.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.rynga.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.samsungsmartcam.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.schlund.de", 3478));
            stunServers.Add(new Tuple <string, int>("stun.services.mozilla.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.sigmavoip.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.sip.us", 3478));
            stunServers.Add(new Tuple <string, int>("stun.sipdiscount.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.sipgate.net", 10000));
            stunServers.Add(new Tuple <string, int>("stun.sipgate.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.siplogin.de", 3478));
            stunServers.Add(new Tuple <string, int>("stun.sipnet.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.sipnet.ru", 3478));
            stunServers.Add(new Tuple <string, int>("stun.siportal.it", 3478));
            stunServers.Add(new Tuple <string, int>("stun.sippeer.dk", 3478));
            stunServers.Add(new Tuple <string, int>("stun.siptraffic.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.skylink.ru", 3478));
            stunServers.Add(new Tuple <string, int>("stun.sma.de", 3478));
            stunServers.Add(new Tuple <string, int>("stun.smartvoip.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.smsdiscount.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.snafu.de", 3478));
            stunServers.Add(new Tuple <string, int>("stun.softjoys.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.solcon.nl", 3478));
            stunServers.Add(new Tuple <string, int>("stun.solnet.ch", 3478));
            stunServers.Add(new Tuple <string, int>("stun.sonetel.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.sonetel.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.sovtest.ru", 3478));
            stunServers.Add(new Tuple <string, int>("stun.speedy.com.ar", 3478));
            stunServers.Add(new Tuple <string, int>("stun.spokn.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.srce.hr", 3478));
            stunServers.Add(new Tuple <string, int>("stun.ssl7.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.stunprotocol.org", 3478));
            stunServers.Add(new Tuple <string, int>("stun.symform.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.symplicity.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.sysadminman.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.t-online.de", 3478));
            stunServers.Add(new Tuple <string, int>("stun.tagan.ru", 3478));
            stunServers.Add(new Tuple <string, int>("stun.tatneft.ru", 3478));
            stunServers.Add(new Tuple <string, int>("stun.teachercreated.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.tel.lu", 3478));
            stunServers.Add(new Tuple <string, int>("stun.telbo.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.telefacil.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.tis-dialog.ru", 3478));
            stunServers.Add(new Tuple <string, int>("stun.tng.de", 3478));
            stunServers.Add(new Tuple <string, int>("stun.twt.it", 3478));
            stunServers.Add(new Tuple <string, int>("stun.u-blox.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.ucallweconn.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.ucsb.edu", 3478));
            stunServers.Add(new Tuple <string, int>("stun.ucw.cz", 3478));
            stunServers.Add(new Tuple <string, int>("stun.uls.co.za", 3478));
            stunServers.Add(new Tuple <string, int>("stun.unseen.is", 3478));
            stunServers.Add(new Tuple <string, int>("stun.usfamily.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.veoh.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.vidyo.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.vipgroup.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.virtual-call.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.viva.gr", 3478));
            stunServers.Add(new Tuple <string, int>("stun.vivox.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.vline.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.vo.lu", 3478));
            stunServers.Add(new Tuple <string, int>("stun.vodafone.ro", 3478));
            stunServers.Add(new Tuple <string, int>("stun.voicetrading.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.voip.aebc.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.voip.blackberry.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.voip.eutelia.it", 3478));
            stunServers.Add(new Tuple <string, int>("stun.voiparound.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.voipblast.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.voipbuster.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.voipbusterpro.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.voipcheap.co.uk", 3478));
            stunServers.Add(new Tuple <string, int>("stun.voipcheap.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.voipfibre.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.voipgain.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.voipgate.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.voipinfocenter.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.voipplanet.nl", 3478));
            stunServers.Add(new Tuple <string, int>("stun.voippro.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.voipraider.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.voipstunt.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.voipwise.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.voipzoom.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.vopium.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.voxgratia.org", 3478));
            stunServers.Add(new Tuple <string, int>("stun.voxox.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.voys.nl", 3478));
            stunServers.Add(new Tuple <string, int>("stun.voztele.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.vyke.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.webcalldirect.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.whoi.edu", 3478));
            stunServers.Add(new Tuple <string, int>("stun.wifirst.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.wwdl.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun.xs4all.nl", 3478));
            stunServers.Add(new Tuple <string, int>("stun.xtratelecom.es", 3478));
            stunServers.Add(new Tuple <string, int>("stun.yesss.at", 3478));
            stunServers.Add(new Tuple <string, int>("stun.zadarma.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.zadv.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun.zoiper.com", 3478));
            stunServers.Add(new Tuple <string, int>("stun1.faktortel.com.au", 3478));
            stunServers.Add(new Tuple <string, int>("stun1.l.google.com", 19302));
            stunServers.Add(new Tuple <string, int>("stun1.voiceeclipse.net", 3478));
            stunServers.Add(new Tuple <string, int>("stun2.l.google.com", 19302));
            stunServers.Add(new Tuple <string, int>("stun3.l.google.com", 19302));
            stunServers.Add(new Tuple <string, int>("stun4.l.google.com", 19302));
            stunServers.Add(new Tuple <string, int>("stunserver.org", 3478));

            Console.WriteLine("Contacting STUN servers to obtain your IP");
            foreach (Tuple <string, int> server in stunServers)
            {
                string host = server.Item1;
                int    port = server.Item2;

                if (!STUNUtils.TryParseHostAndPort($"{host}:{port}", out IPEndPoint stunEndPoint))
                {
                    continue;
                }

                STUNQueryResult stunResult = STUNClient.Query(socket, stunEndPoint, STUNQueryType.ExactNAT, NATTypeDetectionRFC.Rfc3489);

                if (stunResult.QueryError != STUNQueryError.Success)
                {
                    continue;
                }

                Console.WriteLine("Your firewall is {0}", stunResult.NATType);

                return(new P2pEndPoint()
                {
                    External = stunResult.PublicEndPoint,
                    Internal = socket.LocalEndPoint as IPEndPoint
                });
            }

            Console.WriteLine("Could not find a working STUN server");
            return(null);
        }
Beispiel #3
0
        static void Main(string[] args)
        {
            Console.CursorVisible = false;

            Socket     socket           = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            IPEndPoint local_ipendpoint = new IPEndPoint(IPAddress.Any, 1025); //new IPEndPoint(IPAddress.Any, 1025);

            socket.Bind(local_ipendpoint);
            SimpleSTUN.OnDebug += SimpleSTUN_OnDebug;
            STUNQueryResult queryResult = SimpleSTUN.DoSTUN(socket);

//            Task.Run(DoUPNP);
            //var synctask = DoUPNP();
            //synctask.RunSynchronously();


            WebSocket webSocket = new WebSocket("ws://tuxie.nu:10000/ws/excellenthost/");

            webSocket.OnMessage += (sender, eventArgs) =>
            {
                //Console.WriteLine(eventArgs.Data);
                MessageBase messageBase = JsonSerializer.Deserialize <MessageBase>(eventArgs.Data);
                switch (messageBase.type)
                {
                case "EHCONNECT":
                    EHCONNECT ehconnect     = JsonSerializer.Deserialize <EHCONNECT>(eventArgs.Data);
                    string    connectstring = ehconnect.ip + ":" + ehconnect.port.ToString();
                    //                 debugOutput.Add("Got ehconnect");
                    //                 Console.WriteLine(eventArgs.Data);
                    if (!clientThreads.ContainsKey(connectstring) && !(ehconnect.port == queryResult.PublicEndPoint.Port && ehconnect.ip == queryResult.PublicEndPoint.Address.ToString()))
                    {
                        ClientThread ct = new ClientThread();
                        ct.StartClient(ehconnect.ip, ehconnect.port);
                        clientThreads.Add(connectstring, ct);
                        string json = JsonSerializer.Serialize(new EHCONNECT(queryResult.PublicEndPoint.Address.ToString(), queryResult.PublicEndPoint.Port), typeof(EHCONNECT), new JsonSerializerOptions());
                        webSocket.Send(json);
                    }

                    break;
                }
            };

            webSocket.Connect();

            if (queryResult != null)
            {
                new ServerThread().StartServer(socket);
                string json = JsonSerializer.Serialize(new EHCONNECT(queryResult.PublicEndPoint.Address.ToString(), queryResult.PublicEndPoint.Port), typeof(EHCONNECT), new JsonSerializerOptions());
                webSocket.Send(json);
            }

            while (true)
            {
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("Thread status");
                Console.ForegroundColor = ConsoleColor.White;

                foreach (KeyValuePair <string, ClientThread> thread in clientThreads)
                {
                    Console.WriteLine(thread.Value.Status);
                }

                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("Debug output".PadRight(80));
                Console.ForegroundColor = ConsoleColor.White;

                foreach (string line in debugOutput)
                {
                    Console.WriteLine(line);
                }



                Thread.Sleep(1000);
                Console.SetCursorPosition(0, 0);
            }
        }
Beispiel #4
0
        public static STUNQueryResult Query(Socket socket, IPEndPoint server, STUNQueryType queryType, IPAddress[] localIPs, int ReceiveTimeout)
        {
            var result = new STUNQueryResult(); // the query result

            result.Socket         = socket;
            result.ServerEndPoint = server;
            result.NATType        = STUNNATType.Unspecified;
            result.QueryType      = queryType;
            var transID = STUNMessage.GenerateTransactionID();                       // get a random trans id
            var message = new STUNMessage(STUNMessageTypes.BindingRequest, transID); // create a bind request

            // send the request to server
            socket.SendTo(message.GetBytes(), server);
            // we set result local endpoint after calling SendTo,
            // because if socket is unbound, the system will bind it after SendTo call.
            result.LocalEndPoint = socket.LocalEndPoint as IPEndPoint;

            // wait for response
            var responseBuffer = STUNUtils.Receive(socket, ReceiveTimeout);

            // didn't receive anything
            if (responseBuffer == null)
            {
                result.QueryError = STUNQueryError.Timedout;
                return(result);
            }

            // try to parse message
            if (!message.TryParse(responseBuffer))
            {
                result.QueryError = STUNQueryError.BadResponse;
                return(result);
            }

            // check trans id
            if (!STUNUtils.ByteArrayCompare(message.TransactionID, transID))
            {
                result.QueryError = STUNQueryError.BadTransactionID;
                return(result);
            }

            // finds error-code attribute, used in case of binding error
            var errorAttr = message.Attributes.FirstOrDefault(p => p is STUNErrorCodeAttribute)
                            as STUNErrorCodeAttribute;

            // if server responsed our request with error
            if (message.MessageType == STUNMessageTypes.BindingErrorResponse)
            {
                if (errorAttr == null)
                {
                    // we count a binding error without error-code attribute as bad response (no?)
                    result.QueryError = STUNQueryError.BadResponse;
                    return(result);
                }

                result.QueryError        = STUNQueryError.ServerError;
                result.ServerError       = errorAttr.Error;
                result.ServerErrorPhrase = errorAttr.Phrase;
                return(result);
            }

            // return if receive something else binding response
            if (message.MessageType != STUNMessageTypes.BindingResponse)
            {
                result.QueryError = STUNQueryError.BadResponse;
                return(result);
            }

            // not used for now.
            var changedAddr =
                message.Attributes.FirstOrDefault(p => p is STUNChangedAddressAttribute) as
                STUNChangedAddressAttribute;

            // find mapped address attribue in message
            // this attribue should present
            var mappedAddressAttr = message.Attributes.FirstOrDefault(p => p is STUNMappedAddressAttribute)
                                    as STUNMappedAddressAttribute;

            if (mappedAddressAttr == null)
            {
                result.QueryError = STUNQueryError.BadResponse;
                return(result);
            }
            else
            {
                result.PublicEndPoint = mappedAddressAttr.EndPoint;
            }

            // stop querying and return the public ip if user just wanted to know public ip
            if (queryType == STUNQueryType.PublicIP)
            {
                result.QueryError = STUNQueryError.Success;
                return(result);
            }

            // if our local ip and port equals to mapped address
            if (mappedAddressAttr.EndPoint.Equals(socket.LocalEndPoint) || localIPs.Contains(mappedAddressAttr.EndPoint.Address))
            {
                // we send to a binding request again but with change-request attribute
                // that tells to server to response us with different endpoint
                message = new STUNMessage(STUNMessageTypes.BindingRequest, transID);
                message.Attributes.Add(new STUNChangeRequestAttribute(true, true));

                socket.SendTo(message.GetBytes(), server);
                responseBuffer = STUNUtils.Receive(socket, ReceiveTimeout);

                // if we didnt receive a response
                if (responseBuffer == null)
                {
                    result.QueryError = STUNQueryError.Success;
                    result.NATType    = STUNNATType.SymmetricUDPFirewall;
                    return(result);
                }

                if (!message.TryParse(responseBuffer))
                {
                    result.QueryError = STUNQueryError.BadResponse;
                    return(result);
                }

                if (!STUNUtils.ByteArrayCompare(message.TransactionID, transID))
                {
                    result.QueryError = STUNQueryError.BadTransactionID;
                    return(result);
                }

                if (message.MessageType == STUNMessageTypes.BindingResponse)
                {
                    result.QueryError = STUNQueryError.Success;
                    result.NATType    = STUNNATType.OpenInternet;
                    return(result);
                }

                if (message.MessageType == STUNMessageTypes.BindingErrorResponse)
                {
                    errorAttr =
                        message.Attributes.FirstOrDefault(p => p is STUNErrorCodeAttribute) as
                        STUNErrorCodeAttribute;

                    if (errorAttr == null)
                    {
                        result.QueryError = STUNQueryError.BadResponse;
                        return(result);
                    }

                    result.QueryError        = STUNQueryError.ServerError;
                    result.ServerError       = errorAttr.Error;
                    result.ServerErrorPhrase = errorAttr.Phrase;
                    return(result);
                }

                // the message type is wrong
                result.QueryError = STUNQueryError.BadResponse;
                return(result);
            }

            message = new STUNMessage(STUNMessageTypes.BindingRequest, transID);
            message.Attributes.Add(new STUNChangeRequestAttribute(true, true));

            var testmsg = new STUNMessage(STUNMessageTypes.BindingRequest, null);

            testmsg.Parse(message.GetBytes());

            socket.SendTo(message.GetBytes(), server);

            responseBuffer = STUNUtils.Receive(socket, ReceiveTimeout);

            if (responseBuffer != null)
            {
                if (!message.TryParse(responseBuffer))
                {
                    result.QueryError = STUNQueryError.BadResponse;
                    return(result);
                }

                if (!STUNUtils.ByteArrayCompare(message.TransactionID, transID))
                {
                    result.QueryError = STUNQueryError.BadTransactionID;
                    return(result);
                }

                if (message.MessageType == STUNMessageTypes.BindingResponse)
                {
                    result.QueryError = STUNQueryError.Success;
                    result.NATType    = STUNNATType.FullCone;
                    return(result);
                }

                if (message.MessageType == STUNMessageTypes.BindingErrorResponse)
                {
                    errorAttr =
                        message.Attributes.FirstOrDefault(p => p is STUNErrorCodeAttribute) as
                        STUNErrorCodeAttribute;

                    if (errorAttr == null)
                    {
                        result.QueryError = STUNQueryError.BadResponse;
                        return(result);
                    }

                    result.QueryError        = STUNQueryError.ServerError;
                    result.ServerError       = errorAttr.Error;
                    result.ServerErrorPhrase = errorAttr.Phrase;
                    return(result);
                }

                result.QueryError = STUNQueryError.BadResponse;
                return(result);
            }

            // if user only wanted to know the NAT is open or not
            if (queryType == STUNQueryType.OpenNAT)
            {
                result.QueryError = STUNQueryError.Success;
                result.NATType    = STUNNATType.Unspecified;
                return(result);
            }

            // we now need changed-address attribute
            // because we send our request to this address instead of the first server address
            if (changedAddr == null)
            {
                result.QueryError = STUNQueryError.BadResponse;
                return(result);
            }
            else
            {
                server = changedAddr.EndPoint;
            }

            message = new STUNMessage(STUNMessageTypes.BindingRequest, transID);
            socket.SendTo(message.GetBytes(), server);

            responseBuffer = STUNUtils.Receive(socket, ReceiveTimeout);

            if (responseBuffer == null)
            {
                result.QueryError = STUNQueryError.Timedout;
                return(result);
            }

            if (!message.TryParse(responseBuffer))
            {
                result.QueryError = STUNQueryError.BadResponse;
                return(result);
            }

            if (!STUNUtils.ByteArrayCompare(message.TransactionID, transID))
            {
                result.QueryError = STUNQueryError.BadTransactionID;
                return(result);
            }

            errorAttr =
                message.Attributes.FirstOrDefault(p => p is STUNErrorCodeAttribute) as STUNErrorCodeAttribute;

            if (message.MessageType == STUNMessageTypes.BindingErrorResponse)
            {
                if (errorAttr == null)
                {
                    result.QueryError = STUNQueryError.BadResponse;
                    return(result);
                }

                result.QueryError        = STUNQueryError.ServerError;
                result.ServerError       = errorAttr.Error;
                result.ServerErrorPhrase = errorAttr.Phrase;
                return(result);
            }

            if (message.MessageType != STUNMessageTypes.BindingResponse)
            {
                result.QueryError = STUNQueryError.BadResponse;
                return(result);
            }

            mappedAddressAttr = message.Attributes.FirstOrDefault(p => p is STUNMappedAddressAttribute)
                                as STUNMappedAddressAttribute;

            if (mappedAddressAttr == null)
            {
                result.QueryError = STUNQueryError.BadResponse;
                return(result);
            }

            if (!mappedAddressAttr.EndPoint.Equals(result.PublicEndPoint))
            {
                result.QueryError     = STUNQueryError.Success;
                result.NATType        = STUNNATType.Symmetric;
                result.PublicEndPoint = null;
                return(result);
            }

            message = new STUNMessage(STUNMessageTypes.BindingRequest, transID);
            message.Attributes.Add(new STUNChangeRequestAttribute(false, true)); // change port but not ip

            socket.SendTo(message.GetBytes(), server);

            responseBuffer = STUNUtils.Receive(socket, ReceiveTimeout);

            if (responseBuffer == null)
            {
                result.QueryError = STUNQueryError.Success;
                result.NATType    = STUNNATType.PortRestricted;
                return(result);
            }

            if (!message.TryParse(responseBuffer))
            {
                result.QueryError = STUNQueryError.Timedout;
                return(result);
            }

            if (!STUNUtils.ByteArrayCompare(message.TransactionID, transID))
            {
                result.QueryError = STUNQueryError.BadTransactionID;
                return(result);
            }

            errorAttr = message.Attributes.FirstOrDefault(p => p is STUNErrorCodeAttribute)
                        as STUNErrorCodeAttribute;

            if (message.MessageType == STUNMessageTypes.BindingErrorResponse)
            {
                if (errorAttr == null)
                {
                    result.QueryError = STUNQueryError.BadResponse;
                    return(result);
                }

                result.QueryError        = STUNQueryError.ServerError;
                result.ServerError       = errorAttr.Error;
                result.ServerErrorPhrase = errorAttr.Phrase;
                return(result);
            }

            if (message.MessageType != STUNMessageTypes.BindingResponse)
            {
                result.QueryError = STUNQueryError.BadResponse;
                return(result);
            }

            result.QueryError = STUNQueryError.Success;
            result.NATType    = STUNNATType.Restricted;
            return(result);
        }