- Сообщения
- 7,790
- Репутация
- 2,322
AutoIt: 3.3.6.1+
Версия: 1.0
Категория: Интернет
Описание: Про протокол STUN можно прочитать здесь: Способы обхода NAT. Метод STUN. Описание протокола и здесь: RFC5389.
Долгое время для определения внешнего IP-адреса пользовался функцией из этой темы Your public IP (STUN protocol). Почитав про протокол STUN, решил модифицировать функцию trancexx`а, добавив Magic Cookie, что дает возможность получать и обрабатывать ответ не только с атрибутом MAPPED-ADDRESS, но и с XOR-MAPPED-ADDRESS. В итоге получилась практически новая функция.
Код/Пример:
Источник: autoit-script.ru
Автор: madmasles
Версия: 1.0
Категория: Интернет
Описание: Про протокол STUN можно прочитать здесь: Способы обхода NAT. Метод STUN. Описание протокола и здесь: RFC5389.
Долгое время для определения внешнего IP-адреса пользовался функцией из этой темы Your public IP (STUN protocol). Почитав про протокол STUN, решил модифицировать функцию trancexx`а, добавив Magic Cookie, что дает возможность получать и обрабатывать ответ не только с атрибутом MAPPED-ADDRESS, но и с XOR-MAPPED-ADDRESS. В итоге получилась практически новая функция.
Код/Пример:
Код:
Opt('MustDeclareVars', 1)
Global $sIP, $iTimer = TimerInit()
$sIP = _STUN_GetMyIP()
ConsoleWrite(@error & @TAB & $sIP & @TAB & TimerDiff($iTimer) & @LF)
; #FUNCTION# ====================================================================================================
; Name...........: _STUN_GetMyIP
; Description....: Получает внешний IP-адрес компьютера по протоколу STUN.
; Syntax.........: _STUN_GetMyIP()
; Parameters.....: Нет параметров.
; Return values..: Success - внешний IP-адрес компьютора.
; Failure - пустая строка и флаг @error:
; 1 - ошибка UDPStartup();
; 2 - ни один из 15 STUN-серверов не вернул корректного ответа.
; Author.........: madmasles, первоначальный вариант: trancexx (http://www.autoitscript.com/forum/topic/161713-your-public-ip-stun-protocol/)
; Remarks........: Функция работает на много быстрее, чем штатная _GetIP().
; Информация о протоколе STUN:
; http://svitter.info/?p=442
; http://tools.ietf.org/html/rfc5389
; Link...........: http://autoit-script.ru/index.php?topic=19340.0
; Example........: Есть
; ===============================================================================================================
Func _STUN_GetMyIP()
;~ http://svitter.info/?p=442 read about STUN
Local Const $STUN_BINDING_RESPONSE = 257, $STUN_FAMILY_IPV4 = 1, $STUN_MAPPED_ADDRESS = 256, $STUN_XOR_MAPPED_ADDRESS = 8192, _
$a_Data[5][2] = [[28],[33, '.'],[18, '.'],[164, '.'],[66]]
;~ Hex Magic Cookie 21 12 A4 42
;~ Dec Magic Cookie 33 18 164 66
Local $a_Server[17][2] = [[16],['stun.voxgratia.org', 3478],['stun.l.google.com', 19302],['stun1.l.google.com', 19302], _
['stun2.l.google.com', 19302],['stun3.l.google.com', 19302],['stun4.l.google.com', 19302],['stun.ideasip.com', 3478], _
['stun.iptel.org', 3478],['stun.rixtelecom.se', 3478],['stun.schlund.de', 3478],['stun.voiparound.com', 3478], _
['stun.voipbuster.com', 3478],['stun.voipstunt.com', 3478],['stun.ekiga.net', 3478],['stun.sipgate.net', 10000], _
['stun.voxgratia.org', 3478]], $a_Socket[3], $i_Timer, $b_Recv, $i_XOR, $s_MyIP
UDPStartup()
If @error Then Return SetError(1, 0, '')
For $i = 1 To $a_Server[0][0]
If $a_Socket[0] Then UDPCloseSocket($a_Socket)
$a_Server[$i][0] = TCPNameToIP($a_Server[$i][0])
If @error Then ContinueLoop
$a_Socket = UDPOpen($a_Server[$i][0], $a_Server[$i][1])
If Not $a_Socket[0] Then ContinueLoop
;~ header: 0001(Binding Request) 0000(Length) 2112A442(Magic Cookie) 12 byte random ID (All header size = 20 byte)
If UDPSend($a_Socket, Binary('0x000100002112A442') & BinaryMid(Binary(Random()), 3, 6) & BinaryMid(Binary(Random()), 3, 6)) <> 20 Then ContinueLoop
If $i = 1 Then ContinueLoop ; never working first server, I don't know why?
$i_Timer = TimerInit()
Do
$b_Recv = UDPRecv($a_Socket, 88, 1)
If @error Then ExitLoop
If $b_Recv Then ExitLoop
Sleep(10)
Until TimerDiff($i_Timer) > 1000
If (Not $b_Recv) Or (BinaryLen($b_Recv) < 32) Then ContinueLoop
If BinaryMid($b_Recv, 1, 2) <> $STUN_BINDING_RESPONSE Then ContinueLoop
If BinaryMid($b_Recv, 26, 1) <> $STUN_FAMILY_IPV4 Then ContinueLoop
Switch BinaryMid($b_Recv, 21, 2);attribute
Case $STUN_MAPPED_ADDRESS
$i_XOR = 0
Case $STUN_XOR_MAPPED_ADDRESS
$i_XOR = 1
Case Else
$b_Recv = 0
ContinueLoop
EndSwitch
For $j = 1 To 4
If $i_XOR Then
$s_MyIP &= BitXOR(BinaryMid($b_Recv, $a_Data[0][0] + $j, 1), $a_Data[$j][0]) & $a_Data[$j][1]
Else
$s_MyIP &= Int(BinaryMid($b_Recv, $a_Data[0][0] + $j, 1)) & $a_Data[$j][1]
EndIf
Next
ExitLoop
Next
If $a_Socket[0] Then UDPCloseSocket($a_Socket)
UDPShutdown()
If $s_MyIP Then Return $s_MyIP
Return SetError(2, 0, '')
EndFunc ;==>_STUN_GetMyIP
Источник: autoit-script.ru
Автор: madmasles