Results 1 to 14 of 14

Thread: UDP Hole Punch?

Hybrid View

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Oct 2004
    Posts
    259

    UDP Hole Punch?

    Game Server is UPnP enabled. works perfectly.
    Client has no UPnP protocols on their router so it requires manual port settings.

    currently i have:

    Server starts, contacts master server via HTTP request and informs it "This is my port/ip/name/etc..."

    Client
    loads and makes an HTTP request to the master server and gets the serverlist, including our target server.

    Server Listens on: <Server Customized>
    Server Sends To: 45,000

    Client Listens On: 45,000
    Client Sends To: <Server customized>

    Client does HTTP request to a master server to get the target server's IP and <ServerCustomized>port (working)

    The client sends UDP request to the server join the server targeting <ServerCustomized> port. (working)

    Server
    hears the client request (working)
    and replies to client listening port 45000 "yes you may join" (NOT working)

    as far as i can tell, the server is sending it, but the client doesn't hear it.

    to hole punch, do i just need to have the client send the initial join request on both
    <ServerCustomized> port and the 45000 port to punch a hole?

    Q: OMG! Why are you doing hole punching?
    A:Because i've already found 2/3 testers that DONT have upnp routers (eg: WANPPPConnection:1 and WANIPConnection:1).
    ----------------------------------------------------

    Missing the days of GWBasic 1.1
    WaxyStudios.com

  2. #2

    Thread Starter
    Hyperactive Member
    Join Date
    Oct 2004
    Posts
    259

    Re: UDP Hole Punch?

    Bump
    ----------------------------------------------------

    Missing the days of GWBasic 1.1
    WaxyStudios.com

  3. #3
    PowerPoster
    Join Date
    Jul 2006
    Location
    Maldon, Essex. UK
    Posts
    6,334

    Re: UDP Hole Punch?

    Not too sure I fully understand what you're trying to do, 'hole punching' means nothing to me.

    From what I understand, you have a Master Server, some Slave Servers and a some clients.
    When a client wants to 'join in' it communicates with the Master Server, via http protocol, which returns an IP Address and Port Number of a Slave Server to which the client can request connection. Client then uses UDP to the Slave Server which then returns a message agreeing or disagreeing connection. This last messge is not being received by the client. Is that right?

    I don't understand what the final UDP 'conversation' is for. Once the client has an IP Address and Port Number it can use TCP to attempt to connect to the Slave Server. The Slave Server can then decide whether to accept or reject the connection.
    Last edited by Doogle; Feb 6th, 2012 at 03:40 AM.

  4. #4

    Thread Starter
    Hyperactive Member
    Join Date
    Oct 2004
    Posts
    259

    Re: UDP Hole Punch?

    It shouldn't require TCP.

    http://www.brynosaurus.com/pub/net/p2pnat/ (section 3)

    Ok, ever play a game like Quake or something along those lines?
    my master server contains the "Server Browser" information.
    Because it's just simple information retrieval it can, and does, use window's own HTTP protocols with form submission and webpage parsing to get the information for the game server list.
    But the System.Net.WebRequest does not do UDP, only HTTP. so the effectiveness of getting through closed ports stops there.

    Also, because the client has the target information for game servers, the use of the master server stops there.

    The user selects from the list of servers which game to join. (list provided by the master server as stated above)

    This is where the UDP conversation starts. (we are totaly done with the master server until they want to update their list and select a new game server to join)

    The game client then contacts the game host for the UDP handshaking.
    (i've checked over my LAN and the handshaking codeing works fine. glitch isn't there)


    The conversation goes as follows: (all UDP)
    Client -> Server "May i join?"

    Server-> Client "Yes you may. Here's game mode/map/etc.. info" (after checking client space, etc....)

    Client -> Server "Ok, i'm connected" (after loading the required game data from files)

    Server -> All Clients "He joined the game."

    Server <-> Client (back and forth conversation)
    "I Run!"
    "Enemy ducks!"
    "I stop!"
    "Enemy points gun at you!"
    "I draw gun!"
    "You're shot!!!"
    etc....

    If both are UPnP Protocol enabled on the routers then it's not a problem.
    But a lot of hardware out there still isn't UPnP compatible.
    That doesn't stop people on the internet from downloading and playing games without
    having to setup firewall rules, open ports on routers, etc.. etc..
    I'm guessing it's because they are using the method of UDP Hole Punching

    (works on most NOT- UPnP routers by doing "Legal Trickery" to tell the router
    "they are already talking. Port should still be open." even if ports were never manually opened anyway.)

    Server: UPnP enabled. 2way conversation works fine.
    Client: NOT UPnP enabled results in server hearing client, but closed port prevents client from hearing the server.

    because of this problem, people without UPnP routers and lacking "Hole Punching" code in the game will
    end up with this conversation...


    The conversation goes as follows: (all UDP)
    Client -> Server "May i join?"

    Server-> Client "Yes you may. Here's game mode/map/etc.. info" (after checking client space, etc....)

    [server message hit the closed port on the client's router. client didn't hear the response.]

    Client -> Server "Hello? You there? May i join?"

    Server-> Client "Yes you may. Here's game mode/map/etc.. info" (after checking client space, etc....)

    [server message hit the closed port on the client's router. client didn't hear the response.]

    Client -> Server "Hello? You there? May i join?"


    am i making more sense?
    ----------------------------------------------------

    Missing the days of GWBasic 1.1
    WaxyStudios.com

  5. #5

    Thread Starter
    Hyperactive Member
    Join Date
    Oct 2004
    Posts
    259

    Re: UDP Hole Punch?

    PS:
    this pretty picture may better explain the problem
    http://img33.imageshack.us/img33/1448/holepunch1.png

    the details of listen/talk ports are in the first post.
    ----------------------------------------------------

    Missing the days of GWBasic 1.1
    WaxyStudios.com

  6. #6
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: UDP Hole Punch?

    UDP hole punching is pretty old, older than UPnP for that matter. As far as I can tell the most common form of hole punching requires a public server with much more flexibility than a Web server can offer:

    http://en.wikipedia.org/wiki/UDP_hole_punching

    You'd probably have to have a hole-punching server of your own exposed that can receive datagrams on any UDP port.

    Lots of routers that "don't support UPnP" are carrier-provided and hosted NAT routers that won't permit UDP hole punching either, so even if you get this working don't be surprised if it doesn't work for everyone.

  7. #7

    Thread Starter
    Hyperactive Member
    Join Date
    Oct 2004
    Posts
    259

    Re: UDP Hole Punch?

    So if not UDP Hole Punching, then what is the method that
    these other game companies are using to avoid people having
    to manually open ports?

    games like:
    http://battlefield.play4free.com/ battlefield Play For Free
    http://ava.ijji.com Alliance of Valiant Arms
    http://sto.perfectworld.com/ Star Trek Online Free To Play
    and many others.

    My testers play these games but don't have to open their ports manually
    even though their routers aren't UPnP capable.

    Also:
    Quote Originally Posted by dilettante View Post
    As far as I can tell the most common form of hole punching
    requires a public server with much more flexibility than a Web server can offer.
    I'm not looking at having the web server punch the hole, but the game server that the client
    attempts to connect to as part of the connection process.

    But that would be worthless coding and research if UDP Hole Punching isn't the answer.

    The server or server router doesn't need a hole punched. These servers will be manually
    configured by IT educated individuals. just the client or client router will need a hole
    punched.

    Any suggestions?

    Is UDP Hole Punching not the answer?
    ----------------------------------------------------

    Missing the days of GWBasic 1.1
    WaxyStudios.com

  8. #8

    Thread Starter
    Hyperactive Member
    Join Date
    Oct 2004
    Posts
    259

    Re: UDP Hole Punch?

    .

    http://www.brynosaurus.com/pub/net/p2pnat/
    Section 3.2 (paraphrased)
    When GameServer receives GameClient's public and
    private endpoints, GameServer starts sending UDP packets to both
    of these endpoints, and subsequently “locks in” whichever endpoint first elicits
    a valid response from GameClient. The order and timing of these
    messages are not critical as long as they are asynchronous.

    The GameServer - not needing to be hole punched - should be able to
    receive the clients public and private endpoints in the data that was sent
    to it from any UDP Packet, right?

    what i'm thinking is:
    (Server Listener)
    Code:
        Public Sub StartListener()
            ' KEEP
            msg("Public Sub StartListener()")
            Listens = True
            Dim listener As New UdpClient(listenPort)
    
            listener.AllowNatTraversal(True)
            clientSocket.AllowNatTraversal(True)
            ServerSocket.AllowNatTraversal(True)
    
           ' listenport is the <Customized Server Port> to allow multiple servers on the same machine if they can handle it.
           Dim groupEP As New IPEndPoint(IPAddress.Any, listenPort)
            Try
                While Listens 'Listens is set to false upon program close and unload.
                    Dim iData As String
                    Dim bytes As Byte() = listener.Receive(groupEP)
              
                    iData = Replace(Encoding.ASCII.GetString(bytes, 0, bytes.Length), Chr(0), vbNullString) '<-------- ANSWER
                
                    RaiseEvent DataReceived(groupEP.ToString, iData, (CType(listener.Client.LocalEndPoint, IPEndPoint)).Port, (CType(listener.Client.RemoteEndPoint, IPEndPoint)).Port)
                
                End While
            Catch e As Exception
                Console.WriteLine("Error in Start Listener")
                Console.WriteLine(e.ToString())
            Finally
                listener.Close()
            End Try
        End Sub
    i don't understand how this will provide the endpoint ports of the CLIENT that is talking to this GameServer, instead of the server's own endpoints.
    instead, do i need the client to find it's own endpoints somehow and send that information to the GameServer?
    ideas anyone?
    ----------------------------------------------------

    Missing the days of GWBasic 1.1
    WaxyStudios.com

  9. #9

    Thread Starter
    Hyperactive Member
    Join Date
    Oct 2004
    Posts
    259

    Re: UDP Hole Punch?

    Code:
           Private Sub DataReceived(ByVal id As String, ByVal idata As String, _
                                 Optional ByVal EPHelperLocal As Integer = 0, _
                                 Optional ByVal EPHelperRemote As Integer = 0) _
                             Handles HOST.DataReceived
    
    
            ' ID = string containing: ipaddress and sentfrom port format of "XXX.XXX.XXX.XXX:1234"
    
            Dim cName As String
            Dim ChatString As String
    
            Try
    
                ChatString = idata 
    
                If InStr(ChatString, NetworkHeader.ReceiveOrSendChat) Then
    
                    cName = GetClientNicknameFromString(id)
                    ConnectionHistory = ConnectionHistory + " :: " + cName + ":" + id + ":" + Now.ToShortTimeString + "  "
                    ChatString = NetworkHeader.ReceiveOrSendChat & cName & ": " & RemoveLead(idata)
                    BroadcastToAll(ChatString)
                End If
    
                
    
    
    
    ' Section A
                If InStr(ChatString, NetworkHeader.RequestConnection) Then
                    msg("        New player requesting connection: " + ChatString + " | " + id, ConsoleColor.DarkBlue, ConsoleColor.Green)
                    createnewclient(id, idata)
    
                    'PSUDOCODE:
    
                                SendDataToClient(" HOLEPUNCH TEST " & EPHelperLocalPort.Tostring, TO ClientIP:EPHelperLocalPort)
                                SendDataToClient(" HOLEPUNCH TEST " & EPHelperLocalPort.Tostring, TO ClientIP:EPHelperRemotePort)
                                'Client then bounces back port received in a new message.
    
                    'END PSUDOCODE
    
                End If
    
    
     'Section B
                If InStr(ChatString, NetworkHeader.HolePunchReply) Then
                    msg("        New player Setting HolePunchInfo: " + ChatString + " | " + id, ConsoleColor.DarkBlue, ConsoleColor.Green)
                    createnewclient(id, idata)
    
                    'PSUDOCODE:
    
                                HolePunchPort = Val(Port Number Echoed back from Client [see Section A] )
    
                                'edit the data of the client with the new port info received in the data string from Section A
                                EditNewClient(id,HolePunchPort)
    
                    'END PSUDOCODE
    
                End If
    
    'Section OtherCrap
    
                If InStr(ChatString, NetworkHeader.RequestTableUpdate) Then
                    UpdateSingleClientTable(id)
                    msg("NetworkHeader.RequestTableUpdate = Yes")
                End If
    
                If InStr(ChatString, NetworkHeader.IWantToShoot) Then
                    MakeShoot(id, idata)
                End If
    
                'double check those below this line.
                If InStr(ChatString, NetworkHeader.PlayerLocationUpdate) Then
                    '  msg(">> updating location")
                    updateClientLocation(id, ChatString)
                End If
    
                If InStr(ChatString, NetworkHeader.PlayerRotationUpdate) Then
                    ' msg(">> updating rotation")
                    updateClientRotation(id, ChatString)
                End If
    
                If InStr(ChatString, NetworkHeader.Pong) Then
                    UpdatePingInfo(id, ChatString)
                End If
                If InStr(ChatString, NetworkHeader.ClientReady) Then
                    'msg("Received client ready")
                    MarkPlayerReady(id, ChatString)
                End If
            Catch ex As Exception
                msg("error in DataReceived:" + ex.ToString)
            End Try
    
        End Sub
    In relation to the routine in the previous post, then this should hole punch it.
    Sound right? i know there are errors but i'm not sure what they are.
    I'm bouncing ideas off anyone reading this because it takes me so long to get an internet test going with one of my WAN testers.
    So any suggestions/feedback you have would be appreciated.
    ----------------------------------------------------

    Missing the days of GWBasic 1.1
    WaxyStudios.com

  10. #10
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: UDP Hole Punch?

    If the gameserver can be "seen" via portmapping for some UDP port, then clients could send to that UDP port. I believe a normal hole punching server would look at the datagram's source port, and this would be the port it must tell that client to listen on (and the other clients which port to send on to reach that client).

    But I suspect that will fail because when the NAT router near the server maps the datagram's packets inward it is assigning its own source port value, replacing the one from the client's NAT router.

    How do game servers handle this? I suspect that many of them live on the Public Internet (no NAT involved) and can do hole punching or else they relay all traffic between clients.

  11. #11

    Thread Starter
    Hyperactive Member
    Join Date
    Oct 2004
    Posts
    259

    Re: UDP Hole Punch?

    of course my first attempt failed.

    Since the server isn't deaf, can the client simply tell it the clients public and private endpoints for a UDP punch? I'm having trouble understanding all the A's and B's in this part should A or B not require a punch.

    but it sounds like i should:
    1. GameClient finds public and private endpoints for itself after SENDING on the port it listens on to open those ports on self and clientNAT.
    2. GameClient tells GameServer public and private Endpoints
    3. GameServer sends TokenOne and TokenTwo to said endpoints.
    4. GameClient should now be punched and echoes back to GameServer whichever token made it thorough the NAT.
    5. Receiving which ever token was echoed back, the server sets this as the endpoint to send GameClient UDP information.


    do i have this right?

    SECTION 3.4 - Peers behind different NATs
    http://www.brynosaurus.com/pub/net/p2pnat/#fig-diffnat
    (actual section is more detailed)

    A's message to B's public endpoint reaches B's NAT before B's first message to A has crossed B's own NAT, then B's NAT may interpret A's inbound message as unsolicited incoming traffic and drop it. B's first message to A's public address, however, similarly opens a hole in B's NAT, for a new UDP session identified by the endpoints (10.1.1.3:4321, 155.99.25.11:62000) on B's private network, and by the endpoints (138.76.29.7:31000, 155.99.25.11:62000) on the Internet. Once the first messages from A and B have crossed their respective NATs, holes are open in each direction and UDP communication can proceed normally. Once the clients have verified that the public endpoints work, they can stop sending messages to the alternative private endpoints
    ----------------------------------------------------

    Missing the days of GWBasic 1.1
    WaxyStudios.com

  12. #12
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: UDP Hole Punch?

    I believe it is pretty simple: only the clients need hole punching in order to become peers. Only a common server that is both Public and not behind any NAT router can assist in this.

    If the server is behind a NAT router then it will never see the correct UDP source port numbers of the clients' routers.

    See http://en.wikipedia.org/wiki/UDP_hol...hing#Algorithm

    You might get lucky once in a while if some client's routers do not randomize the source port numbers.

  13. #13

    Thread Starter
    Hyperactive Member
    Join Date
    Oct 2004
    Posts
    259

    Re: UDP Hole Punch?

    If the server is behind a NAT router then it will never see the correct UDP source port numbers of the clients' routers......You might get lucky once in a while if some client's routers do not randomize the source port numbers.
    So even if i used a library to find the public and private endpoints on the client by the client (rather than by the server) - then randomization will still be a major roadblock.
    Grrr. bummer.
    ----------------------------------------------------

    Missing the days of GWBasic 1.1
    WaxyStudios.com

  14. #14
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: UDP Hole Punch?

    Looks like it. If an easy answer was available we'd probably have tons of sample code to choose from.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width