UDP Hole Punching - P2P

  • PHP

Es gibt 3 Antworten in diesem Thema. Der letzte Beitrag () ist von BeefyX.

    UDP Hole Punching - P2P

    Hallooo Leute..
    Nach lange suchen bei Google und jeder Menge Wikipedia blieb ich doch stecken, bei meinem Problem...
    Ich habe einen UDP Server ("Master Server"), der immer Port 8000 hat (beispiel).
    Master Server ist einfach mal der hier: 200.200.100.100:8000
    Dann habe ich Client A (LAN: 192.168.2.117:5123 WAN: 217.232.200.100:13337) und
    Client B (LAN: 192.168.1.143:7851 WAN: 142.85.33.123:9412).
    Per Packets von beiden Clienten hat mein Master Server nun die LAN und WAN daten gesammelt.
    Der Master Server sendet nun die Daten von Client A zu Client B. Und zu Client A sendet er die von Client B.
    Nun dürften beide eigentlich miteinander kommunizieren? (Man beachte: [bei mir jedenfalls] ist der LAN Port immer wie der WAN Port).

    Also so in etwa ist das dann:

    192.168.2.117:5123 -> 217.232.200.100:13337 -> 200.200.100.100:8000
    192.168.1.143:7851 -> 142.85.33.123:9412 -> 200.200.100.100:8000
    200.200.100.100:8000
    sagt 217.232.200.100:13337 soll auf 142.85.33.123:9412 verbinden.
    200.200.100.100:8000 sagt 142.85.33.123:9412 soll auf 217.232.200.100:13337 verbinden.

    Also siehts so aus:

    192.168.2.117:5123 -> 217.232.200.100:13337 -> 142.85.33.123:9412 -> 192.168.1.143:7851

    Und wieso geht das bei mir nicht?
    Oder habe ich das mit dem Hole Punching / P2P nicht wirklich verstanden?
    Soweit ich weiss wird (wenn ich iwo hin connecte) ein lokaler port bei mir temporär geöffnet: Also z.b. 9412, 7851, 5123 oder 13337 (LAN und WAN Port? Weiss ich nicht genau...).

    Könnte mir das bitte jemand besser erklären als bei Wikipedia?
    Oder mir was nützliches geben?
    Ich bin schon am verzweifeln!

    Edit by nikeee13:
    Da es sich hier wohl um eine PHP-Frage handelt: Topic verschoben.
    Außerdem: Die Farbe Rot ist den Moderatoren vorbehalten.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „nikeee13“ ()

    derp, doch klar. du musst den selben socket nutzen den du auch zum ermitteln des ports genutzt hast. der client darf afaik auch keine antwort kriegen, allerdings hat sone connection auch nen timeout, meist ne minute oderso. es gibt auch router die bei jeder connection nen neuen random port oeffnen, da funktionieet das ganze nicht

    edit: zeig uns doch mal dein code
    Naja es geht hier um ein Server für ein Spiel... Nur für mich, was privates.

    udpserver.php
    Spoiler anzeigen

    PHP-Quellcode

    1. <?php
    2. include("functions.php");
    3. $strServerIp = '0.0.0.0';
    4. $intServerPort = 5350;
    5. WriteLine("Server", "Server starting ".$strServerIp.":".$intServerPort." ...");
    6. include("data.php");
    7. include("data/mysql.php");
    8. $objMysql = new MysqlClass($arrMysqlData['host'], $arrMysqlData['user'], $arrMysqlData['password'], $arrMysqlData['database']);
    9. WriteLine("MySQL", "Successfully connected to ".$objMysql->getHost()." as '".$objMysql->getUser()."'");
    10. $objServer = stream_socket_server("udp://".$strServerIp.":".$intServerPort, $errno, $errstr, STREAM_SERVER_BIND);
    11. $arrIpData = array();
    12. if($objServer)
    13. {
    14. WriteLine("Server", "Server running on ".$strServerIp.":".$intServerPort." !");
    15. while(true)
    16. {
    17. $strReceived = stream_socket_recvfrom($objServer, 1024, 0, $objPeer);
    18. $strAnalyzedPacket = analyzePacket($strReceived, $objPeer);
    19. stream_socket_sendto($objServer, $strAnalyzedPacket, 0, $objPeer);
    20. }
    21. }
    22. else
    23. {
    24. WriteLine("Server", "Could not start UDP Server on '".$strServerIp.":".$intServerPort);
    25. WriteLine("Server", "Error #".$errno);
    26. WriteLine("Server", $errstr);
    27. }
    28. function analyzePacket($strInput, $strFrom)
    29. {
    30. global $arrIpData;
    31. global $objMysql;
    32. global $objServer;
    33. $arrChars = array();
    34. for($intIndex = 0; $intIndex < strlen($strInput); $intIndex ++)
    35. {
    36. $arrChars[] = ord($strInput[$intIndex]);
    37. }
    38. $arrOutput = array();
    39. //if(isset($strFrom) && isset($strInput) && isValidAddress($strFrom) == true && strlen($strInput > 4))
    40. if(true)
    41. {
    42. if($arrChars[0] == 0x10 && $arrChars[1] == 0x1 && $arrChars[2] == 0x1)
    43. {
    44. $arrOutput = array(0x10, 0x1, 0x1, 0x0, 0x14, 0xE6, 0x0, 0x0, 0x0, 0x0);
    45. $arrOutput[] = $arrChars[count($arrChars) - 4];
    46. $arrOutput[] = $arrChars[count($arrChars) - 3];
    47. $arrOutput[] = $arrChars[count($arrChars) - 2];
    48. $arrOutput[] = $arrChars[count($arrChars) - 1];
    49. $intUserId = bytesToDecimal(array($arrChars[count($arrChars) - 1], $arrChars[count($arrChars) - 2], $arrChars[count($arrChars) - 3], $arrChars[count($arrChars) - 4]));
    50. $arrIpData[$strFrom] = array();
    51. $arrIpData[$strFrom]['id'] = $intUserId;
    52. }
    53. elseif($arrChars[0] == 0x10 && $arrChars[1] == 0x10 && $arrChars[2] == 0x0 && $arrChars[14] == 0x21)
    54. {
    55. /*$arrOutput = array(0x10, 0x10, 0x0, 0x0, 0x0, 0x4,
    56. 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x0, 0x0, 0x0, 0x21,
    57. 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    58. 0x0, 0x0, 0x0, 0x1, 0x11, 0x13, 0x11, 0xDF, 0x21,
    59. 0xA1, 0x15, 0xBE, 0x1B, 0x11, 0x11, 0x11, 0x11,
    60. 0x11, 0x11, 0x11, 0x11, 0x1, 0x11, 0x13, 0x11,
    61. 0xF9, 0xEA, 0x1B, 0xC0, 0xBE, 0x1B, 0x19, 0x19,
    62. 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x11);*/
    63. if(!isset($arrIpData[$strFrom]) || !is_array($arrIpData[$strFrom])) //packet is not authed
    64. {
    65. WriteLine("Server", "Cross Packet from ".$strFrom);
    66. return;
    67. }
    68. $arrKeys = array(0x25, 0x10, 0x2525, 0x1010); //server key, client key
    69. // REMOTE STUFF
    70. $arrAddress = explode(":", $strFrom);
    71. $strRemoteIP = $arrAddress[0];
    72. $intRemotePort = $arrAddress[1];
    73. $arrRemoteIP = explode(".", $strRemoteIP);
    74. $arrRemotePort = splitInt($intRemotePort);
    75. $arrIpData[$strFrom]['remoteip'] = $strRemoteIP;
    76. array_reverse($arrRemotePort); //fasten make good crap
    77. $intRemotePort = bytesToDecimal($arrRemotePort);
    78. $arrIpData[$strFrom]['remoteport'] = $intRemotePort;
    79. // LOCAL STUFF
    80. $arrLocalIP = array($arrChars[34], $arrChars[35], $arrChars[36], $arrChars[37]);
    81. $arrLocalIP[0] = XorFix($arrLocalIP[0], $arrKeys[1]);
    82. $arrLocalIP[1] = XorFix($arrLocalIP[1], $arrKeys[1]);
    83. $arrLocalIP[2] = XorFix($arrLocalIP[2], $arrKeys[1]);
    84. $arrLocalIP[3] = XorFix($arrLocalIP[3], $arrKeys[1]);
    85. array_reverse($arrLocalIP);
    86. $strLocalIP = implode(".", $arrLocalIP);
    87. $arrLocalPort = array($arrChars[32], $arrChars[33]);
    88. $arrLocalPort[0] = XorFix($arrLocalPort[0], $arrKeys[1]);
    89. $arrLocalPort[1] = XorFix($arrLocalPort[1], $arrKeys[1]);
    90. //array_reverse($arrLocalPort);
    91. $intLocalPort = bytesToDecimal($arrLocalPort);
    92. $arrIpData[$strFrom]['localip'] = $strLocalIP;
    93. $arrIpData[$strFrom]['localport'] = $intLocalPort;
    94. array_reverse($arrRemoteIP);
    95. $intRemoteDecimal = bytesToDecimal($arrRemoteIP);
    96. $intLocalDecimal = bytesToDecimal($arrLocalIP);
    97. WriteLine("UDP", "Setting network for #".$arrIpData[$strFrom]['id']." [".$strFrom."] to [".$intRemoteDecimal.":".$intRemotePort." ; ".$intLocalDecimal.":".$intLocalPort." (".$strLocalIP.":".$intLocalPort.")]");
    98. $objMysql->query("UPDATE `peer` SET `remoteip` = '".$arrIpData[$strFrom]['remoteip']."', `remoteport` = '".$arrIpData[$strFrom]['remoteport']."', `localip` = '".$arrIpData[$strFrom]['localip']."', `localport` = '".$arrIpData[$strFrom]['localport']."', `c_remoteip`='".$intRemoteDecimal."', `c_localip`='".$intLocalDecimal."' WHERE `peer`.`userid` = '".$arrIpData[$strFrom]['id']."';");
    99. // MAKE GOOD STUFF OUT OF IT (REMOTE)
    100. $arrRemoteIP[0] = XorFix($arrRemoteIP[0], $arrKeys[0]);
    101. $arrRemoteIP[1] = XorFix($arrRemoteIP[1], $arrKeys[0]);
    102. $arrRemoteIP[2] = XorFix($arrRemoteIP[2], $arrKeys[0]);
    103. $arrRemoteIP[3] = XorFix($arrRemoteIP[3], $arrKeys[0]);
    104. $arrRemotePort[0] = XorFix($arrRemotePort[0], $arrKeys[0]);
    105. $arrRemotePort[1] = XorFix($arrRemotePort[1], $arrKeys[0]);
    106. // MAKE GOOD STUFF OUT OF IT (LOCAL)
    107. $arrLocalIP[0] = XorFix($arrLocalIP[0], $arrKeys[0]);
    108. $arrLocalIP[1] = XorFix($arrLocalIP[1], $arrKeys[0]);
    109. $arrLocalIP[2] = XorFix($arrLocalIP[2], $arrKeys[0]);
    110. $arrLocalIP[3] = XorFix($arrLocalIP[3], $arrKeys[0]);
    111. array_reverse($arrLocalIP);
    112. $arrLocalPort[0] = XorFix($arrLocalPort[0], $arrKeys[0]);
    113. $arrLocalPort[1] = XorFix($arrLocalPort[1], $arrKeys[0]);
    114. array_reverse($arrLocalPort);
    115. $arrOutput = array(0x10, 0x10, 0x00, 0x00, $arrChars[4], $arrChars[5],
    116. 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x21,
    117. 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    118. 0x0, 0x0, 0x0, 0x35, 0x25, 0x27, 0x25, $arrRemotePort[0], $arrRemotePort[1],
    119. $arrRemoteIP[0], $arrRemoteIP[1], $arrRemoteIP[2], $arrRemoteIP[3],
    120. 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x35,
    121. 0x25, 0x27, 0x25, $arrLocalPort[0], $arrLocalPort[1],
    122. $arrLocalIP[3], $arrLocalIP[2], $arrLocalIP[1], $arrLocalIP[0],
    123. 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x25);
    124. /*
    125. 0xDF 0x21 -> 0xF6 0x3A
    126. 0xF9 0xEA -> 0xCD 0x74
    127. 0xA1 0x15 0xBE 0x1B -> 0x3F 0x62 0x20 0x85
    128. 0xCD 0x74 -> 0xEA 0x19
    129. OLD
    130. $arrOutput = array(0x10, 0x10, 0x0, 0x0, 0x2, 0x3B,
    131. 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x0, 0x0, 0x0, 0x21,
    132. 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    133. 0x0, 0x0, 0x0, 0x1, 0x11, 0x13, 0x11, 0x1F, 0x19,
    134. 0xC8, 0xF9, 0x53, 0x96, 0x11, 0x11, 0x11, 0x11,
    135. 0x11, 0x11, 0x11, 0x11, 0x1, 0x11, 0x13, 0x11,
    136. 0x1F, 0x19, 0x1A, 0x7, 0x30, 0x3D, 0x19, 0x19,
    137. 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x11);
    138. */
    139. }
    140. elseif($arrChars[0] == 0x10 && $arrChars[1] == 0x10 && $arrChars[2] == 0x0 && $arrChars[14] == 0x31)
    141. {
    142. foreach($arrIpData as $strKey => $strValue)
    143. {
    144. //stream_socket_sendto($objServer, arrToString($arrChars), 0, $strKey);
    145. }
    146. }
    147. else
    148. {
    149. WriteLine("UDP", "Uknown packet: ".hexString($strInput));
    150. }
    151. }
    152. else
    153. {
    154. WriteLine("UDP", "Invalid UDP Packet from ".$strFrom."!");
    155. }
    156. return arrToString($arrOutput);
    157. }
    158. function arrToString($arrInput)
    159. {
    160. $strOutput = '';
    161. for($intIndex = 0; $intIndex < count($arrInput); $intIndex ++)
    162. {
    163. $strOutput .= chr($arrInput[$intIndex]);
    164. }
    165. return $strOutput;
    166. }
    167. function splitInt($intInput)
    168. {
    169. $strBinary = decbin($intInput);
    170. if(strlen($strBinary) < 16)
    171. {
    172. for($intIndex = strlen($strBinary); $intIndex < 16; $intIndex ++)
    173. {
    174. $strBinary = "0" . $strBinary;
    175. }
    176. }
    177. $intByteA = $strBinary[0].$strBinary[1].$strBinary[2].$strBinary[3].$strBinary[4].$strBinary[5].$strBinary[6].$strBinary[7];
    178. $intByteB = $strBinary[8].$strBinary[9].$strBinary[10].$strBinary[11].$strBinary[12].$strBinary[13].$strBinary[14].$strBinary[15];
    179. return array(bindec($intByteA), bindec($intByteB));
    180. }
    181. function hexString($strInput)
    182. {
    183. $strFinalHex = '';
    184. for($intIndex = 0; $intIndex < strlen($strInput); $intIndex ++)
    185. {
    186. $strFinalHex .= dechex(ord($strInput[$intIndex])). " ";
    187. }
    188. return $strFinalHex;
    189. }
    190. function isValidAddress($strAddress)
    191. {
    192. $arrAddress = explode(":", $strAddress);
    193. if(count($arrAddress) != 2)
    194. {
    195. return false;
    196. }
    197. $strIP = $arrAddress[0];
    198. $intPort = $arrAddress[1];
    199. if(is_numeric($intPort) && $intPort > 0 && $intPort < 65536)
    200. {
    201. $arrIP = explode(".", $strIp);
    202. if(count($arrIp) == 4 && is_numeric($arrIP[0]) && is_numeric($arrIP[1]) && is_numeric($arrIP[2]) && is_numeric($arrIP[3]))
    203. {
    204. return true;
    205. }
    206. }
    207. else
    208. {
    209. return false;
    210. }
    211. }
    212. function ip2ulong($arrIpAddress)
    213. {
    214. return $arrIpAddress[0] << 24 + $arrIpAddress[1] << 16 + $arrIpAddress[2] << 8 + $arrIpAddress[3];
    215. }
    216. ?>



    network/game/29952_playerlist.php
    Spoiler anzeigen

    PHP-Quellcode

    1. <?php
    2. class gSvPlayerlist extends Packet
    3. {
    4. public function __construct($arrPlayers, $objRoom, $objSelf = NULL)
    5. {
    6. global $GameOperationcodes;
    7. parent::__construct(Crypter::PACKETTYPE_Game(), $GameOperationcodes['SvPlayersInRoom']);
    8. $this->addBlock(count($arrPlayers)); // + 24);
    9. $objMarlon = NULL;
    10. foreach($arrPlayers as $objHandler)
    11. {
    12. $objPlayer = $objHandler->getUser();
    13. $objPlayer->refreshIpData();
    14. $this->addBlock($objPlayer->getUserId());
    15. $this->addBlock($objPlayer->getSessionId());
    16. $this->addBlock($objRoom->getPlayerSlot($objHandler));
    17. $this->addBlock($objPlayer->getReadyState());
    18. $this->addBlock($objRoom->getTeam($objHandler));
    19. $this->addBlock(0);
    20. $this->addBlock(0);
    21. $this->addBlock(0);
    22. $this->addBlock(1000);
    23. $this->addBlock($objPlayer->getNickname());
    24. $this->addBlock(-1); //clan id?
    25. $this->addBlock(-1); //clan member?
    26. $this->addBlock(-1); //wtf
    27. $this->addBlock($objPlayer->getUserId() + 1);
    28. $this->addBlock($objPlayer->getUserId());
    29. $this->addBlock($objPlayer->getUniqId());
    30. $this->addBlock($objPlayer->getPremium());
    31. $this->addBlock(0);
    32. $this->addBlock(-1);
    33. $this->addBlock($objPlayer->getKills());
    34. $this->addBlock($objPlayer->getDeaths());
    35. $this->addBlock(1000);
    36. $this->addBlock($objPlayer->getExp());
    37. $this->addBlock(-1);
    38. $this->addBlock(-1);
    39. if($objHandler == $objRoom->getMaster())
    40. {
    41. $this->addBlock("ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ");
    42. }
    43. else
    44. {
    45. $this->addBlock(1);
    46. }
    47. $this->addBlock($objPlayer->getIpData('remote'));
    48. $this->addBlock($objPlayer->getIpData('remotep'));
    49. $this->addBlock($objPlayer->getIpData('local'));
    50. $this->addBlock($objPlayer->getIpData('localp'));
    51. $this->addBlock(0);
    52. }
    53. echo $this->getPacket()."\n";
    54. /* global $objMysql;
    55. for($intIndex = 8; $intIndex < 32; $intIndex ++)
    56. {
    57. $objPlayer = $objMarlon->getUser();
    58. $this->addBlock($objPlayer->getUserId() + 1);
    59. $this->addBlock($objPlayer->getSessionId() + 1);
    60. $this->addBlock($intIndex);
    61. $this->addBlock($objPlayer->getReadyState());
    62. $this->addBlock(1);
    63. $this->addBlock(0);
    64. $this->addBlock(0);
    65. $this->addBlock(0);
    66. $this->addBlock(1000);
    67. $this->addBlock($objPlayer->getNickname()."-TestFucker".$intIndex);
    68. $this->addBlock(-1);
    69. $this->addBlock(-1);
    70. $this->addBlock(-1);
    71. $this->addBlock(0);
    72. $this->addBlock(19);
    73. $this->addBlock(910);
    74. $this->addBlock($objPlayer->getPremium());
    75. $this->addBlock(0);
    76. $this->addBlock(-1);
    77. $this->addBlock($objPlayer->getKills());
    78. $this->addBlock($objPlayer->getDeaths());
    79. $this->addBlock(551513);
    80. $this->addBlock($objPlayer->getExp());
    81. $this->addBlock(-1);
    82. $this->addBlock(-1);
    83. $this->addBlock(1); //can be yyyyyy too...
    84. $this->addBlock($objPlayer->getIpData('remote'));
    85. $objQuery = $objMysql->query("SELECT `port` FROM `marlon` WHERE `id`='".$intIndex."'");
    86. $objRow = mysql_fetch_array($objQuery);
    87. $this->addBlock($objRow['port']);
    88. $this->addBlock($objPlayer->getIpData('local'));
    89. $this->addBlock($objRow['port']);
    90. $this->addBlock(0);
    91. }
    92. WriteLine("Game", $this->getPacket()); */
    93. }
    94. }
    95. ?>



    Edit by nikeee13:
    Bei langen Codeausschnitten bitte den Expander-Tag verwenden!
    Expander hinzugefügt.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „nikeee13“ ()