Quantcast
Channel: AutoIt v3 - General Help and Support
Viewing all articles
Browse latest Browse all 12506

getaddrinfo timeout

$
0
0

Hi,

 

I was looking for a multi threading Ping and found this post (http://www.autoitscript.com/forum/topic/106354-threaded-ping/?p=766946&hl=ping%20thread&fromsearch=1#entry766946) from Fr0zt.

His Ping in assembly is impressive (adapted from the trancexx's and monoceres work  http://www.autoitscript.com/forum/topic/95510-execute-in-a-different-thread/).

AutoIt         
#include <Memory.au3> #include <Array.au3> Opt('MustDeclareVars', 1) HotKeySet("{ESC}", "_Exit") Global Const $DONT_FRAGMENT = 2, $IP_SUCCESS = 0, $IP_DEST_NET_UNREACHABLE = 11002, $IP_DEST_HOST_UNREACHABLE = 11003, $IP_DEST_PROT_UNREACHABLE = 11004, $IP_DEST_PORT_UNREACHABLE = 11005, _     $IP_NO_RESOURCES = 11006, $IP_HW_ERROR = 11008, $IP_PACKET_TOO_BIG = 11009, $IP_REQ_TIMED_OUT = 11010, $IP_BAD_REQ = 11011, $IP_BAD_ROUTE = 11012, _     $IP_TTL_EXPIRED_TRANSIT = 11013, $IP_TTL_EXPIRED_REASSEM = 11014, $IP_PARAM_PROBLEM = 11015, $IP_SOURCE_QUENCH = 11016, $IP_BAD_DESTINATION =11018, _     $IP_GENERAL_FAILURE = 11050, $NO_STATUS = 10000     ;We will use 10000 as the no status indicator since 0 meens successful reply Local $hPointers = DllStructCreate("ptr IcmpCloseHandle;ptr IcmpSendEcho;ptr IcmpCreateFile;ptr ExitThread") Global $hkernel32Dll = DllOpen("kernel32.dll") Global $hKrn = _WinAPI_GetModuleHandle("kernel32.dll") DllStructSetData($hPointers,"ExitThread",GetProcAddress($hKrn, "ExitThread")) Global $hICMPDll = LibLoad("ICMP.dll");Iphlpapi.dll") DllStructSetData($hPointers,"IcmpCloseHandle",GetProcAddress($hICMPDll, "IcmpCloseHandle")) DllStructSetData($hPointers,"IcmpSendEcho",GetProcAddress($hICMPDll, "IcmpSendEcho")) DllStructSetData($hPointers,"IcmpCreateFile",GetProcAddress($hICMPDll, "IcmpCreateFile")) TCPStartup() ;This is required, not only to do DNS lookup, but also for WSAStartup() Global $pings[1]  = [0]  ;This array will hold all echo reply data in a struct. ConsoleWrite("Press esc any time to stop" & @CRLF) pingThreaded("www.google.ca") pingThreaded("www.asus.com.tw") Local $pingdata = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" Local $timeout = 150 Local $ttl = 255 pingThreaded("www.autoitscript.com", $timeout, $pingdata, $ttl, $DONT_FRAGMENT) While 1     _managePings() WEnd ;Function pingThreaded ;$ip_addr will accept valid DNS Name or Normal IP address. ;Timouts only really work when an IP isn't responding. Thats important to remember because if you think you can timeout an IP which has latent responces, you can't! Func pingThreaded($ip_addr, $timeout=5000, $data="x", $ttl=255, $flags=0)     Local $hexIP = encodeIP($ip_addr)     If $hexIP == 0 Then Return 0     Local $pingID = _addPing($ip_addr)     If IsNumber($ttl) = 0 Or Number($ttl) > 255 Then $ttl = 255     If IsNumber($timeout) = 0 Or Number($timeout) > 5000 Then $timeout = 5000     If StringLen($data) > 256 Then $data = StringTrimRight($data,StringLen($data) - 256)     If IsNumber($flags) = 0 Or Number($flags) > 2 Then $flags = 2     DllStructSetData($pings[$pingID],"datasize",StringLen($data))   ;We may wish to report the data size later     ;Props to trancexx     Local $CodeBuffer = DllStructCreate("byte[696]"); Code=154, Data=256, Echo reply Struct + ICMP_OPTIONS Struct = 286     Local $RemoteCode = _MemVirtualAlloc(0, DllStructGetSize($CodeBuffer), $MEM_COMMIT, $PAGE_EXECUTE_READWRITE)     DllStructSetData($CodeBuffer, 1, _         "0x" & _                                                            ;Original Assembly started at 401000         "E889000000" & _                                                ;Call 0040108E  <IcmpCreateFile>         "A3" & SwapEndian($RemoteCode + 410) & _                            ;mov dword ptr [00403010], eax  <hIcmp = IcmpCreateFile Handle>         "C605" & SwapEndian($RemoteCode + 418) & Hex($ttl,2) & _            ;mov byte ptr [00403024], xx    <TTL>         "C605" & SwapEndian($RemoteCode + 419) & "00" & _                                   ;mov byte ptr [00403025], 00    <TOS>         "C605" & SwapEndian($RemoteCode + 420) & Hex($flags,2) & _          ;mov byte ptr [00403026], 02    <Flags, 0x02=DF Bit Set>         "C605" & SwapEndian($RemoteCode + 421) & "00" & _                   ;mov byte ptr [00403027], 00         "C705" & SwapEndian($RemoteCode + 422) & "00000000" & _         ;mov dword ptr [00403028], 00000000         "68" & SwapEndian(Dec(Hex($timeout,4))) & _                                 ;push 0000xxxx  <Timeout>         "681E010000" & _                                                ;push 0000011E  <Size of Echo reply Struct + ICMP_OPTIONS Struct>         "68" & SwapEndian($RemoteCode + 426) & _                            ;push 0040302C  <icmpReply>         "68" & SwapEndian($RemoteCode + 418) & _                            ;push 00403024  <icmpOptions>         "6A" & Hex(StringLen($data),2) & _                                  ;push 000000xx  <Data Size>         "68" & SwapEndian($RemoteCode + 154) & _                            ;push 00403000  <Data>         "68" & SwapEndian(Dec($hexIP)) & _                              ;push <Hex(IP ADDRESS)>         "FF35" & SwapEndian($RemoteCode + 410) & _                      ;push dword ptr [00403010]  <hIcmp>         "E839000000" & _                                                ;Call 00401094  <IcmpSendEcho>         "A1" & SwapEndian($RemoteCode + 434) & _                            ;mov eax, dword ptr [00403034]  <Get the ms responce time from icmpReply.RoundTripTime>         "A3" & SwapEndian(DllStructGetPtr($pings[$pingID],"reply")) & _         ;mov dword ptr [0040301C], eax  <Store the ms responce time>         "A1" & SwapEndian($RemoteCode + 430) & _                            ;mov eax, dword ptr [00403030]  <Get the status from icmpReply.Status>         "A3" & SwapEndian(DllStructGetPtr($pings[$pingID],"status")) & _        ;mov dword ptr [00403020], eax  <Store the status>         "FF35" & SwapEndian($RemoteCode + 410) & _                      ;push dword ptr [00403010]  <hIcmp>         "E80E000000" & _                                                ;Call 00401088  <IcmpCloseHandle>         "6A00" & _                                                      ;push 00000000         "E801000000" & _                                                ;Call 00401082  <ExitThread>         "CC" & _                                                            ;int 03         "FF25" & SwapEndian(DllStructGetPtr($hPointers,"ExitThread")) & _       ;JMP dword ptr  <kernel32.ExitThread>         "FF25" & SwapEndian(DllStructGetPtr($hPointers,"IcmpCloseHandle")) & _  ;JMP dword ptr  <ICMP.IcmpCloseHandle>         "FF25" & SwapEndian(DllStructGetPtr($hPointers,"IcmpCreateFile")) & _   ;JMP dword ptr  <ICMP.IcmpCreateFile>         "FF25" & SwapEndian(DllStructGetPtr($hPointers,"IcmpSendEcho"))& _  ;JMP dword ptr  <ICMP.IcmpSendEcho>         SwapEndian(StringToBinary($data)) _                             ;This is our ping Data, Max 256 bytes of space here.     )     _MemMoveMemory(DllStructGetPtr($CodeBuffer), $RemoteCode, DllStructGetSize($CodeBuffer))     Local $aCall = DllCall($hkernel32Dll, "ptr", "CreateThread", "ptr", 0, "int", 0, "ptr", $RemoteCode, "ptr", 0, "int", 0, "dword*", 0)     Return $aCall[0] EndFunc ;Function _addPing is just for array management of the $pings[] array. Func _addPing($ip_addr)     $pings[0] = UBound($pings)     ReDim $pings[$pings[0]+1]     $pings[$pings[0]] = DllStructCreate("char ip[" & StringLen($ip_addr) & "];ulong reply;ulong status;int datasize");You could add a timeout struct here     DllStructSetData($pings[$pings[0]],"ip",$ip_addr)     DllStructSetData($pings[$pings[0]],"status",$NO_STATUS)     Return $pings[0] EndFunc ;Function _removePing is just for array management of the $pings[] array. Func _removePing($pingID)     If $pingID > $pings[0] Then Return ;Ensure our ID is valid     $pings[$pingID] = 0 ;Free the DLLStruct     _ArrayDelete($pings,$pingID)     $pings[0] -= 1 EndFunc ;Function _managePings() ;This is where the reply's get sorted out, and actions taken Func _managePings()     Local $pingID, $status     $pingID = 1     While $pingID <= $pings[0]         $status = DllStructGetData($pings[$pingID],"status")         If $status <> $NO_STATUS Then             Switch $status                 Case $IP_SUCCESS                     If DllStructGetData($pings[$pingID],"reply") = 0 Then                         ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " replied in <1ms" & @CRLF)                     Else                         ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " replied in " & DllStructGetData($pings[$pingID],"reply") & "ms" & @CRLF)                     EndIf                 Case $IP_REQ_TIMED_OUT                     ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " timed-out" & @CRLF)                 Case $IP_DEST_NET_UNREACHABLE                     ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " The destination network was unreachable." & @CRLF)                 Case $IP_DEST_HOST_UNREACHABLE                     ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " The destination host was unreachable." & @CRLF)                 Case $IP_DEST_PROT_UNREACHABLE                     ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " The destination protocol was unreachable." & @CRLF)                 Case $IP_DEST_PORT_UNREACHABLE                     ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " The destination port was unreachable." & @CRLF)                 Case $IP_NO_RESOURCES                     ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " Insufficient IP resources were available." & @CRLF)                 Case $IP_HW_ERROR                     ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " A hardware error occurred." & @CRLF)                 Case $IP_PACKET_TOO_BIG                     ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " The packet was too big." & @CRLF)                 Case $IP_BAD_REQ                     ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " A bad request." & @CRLF)                 Case $IP_BAD_ROUTE                     ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " A bad route." & @CRLF)                 Case $IP_TTL_EXPIRED_TRANSIT                     ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " The time to live (TTL) expired in transit." & @CRLF)                 Case $IP_TTL_EXPIRED_REASSEM                     ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " The time to live expired during fragment reassembly." & @CRLF)                 Case $IP_PARAM_PROBLEM                     ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " A parameter problem." & @CRLF)                 Case $IP_SOURCE_QUENCH                     ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " Datagrams are arriving too fast to be processed and datagrams may have been discarded." & @CRLF)                 Case $IP_BAD_DESTINATION                     ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " A bad destination." & @CRLF)                 Case $IP_GENERAL_FAILURE                     ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " A general failure. This error can be returned for some malformed ICMP packets or lost network connection." & @CRLF)             EndSwitch             _removePing($pingID)     EndIf ;   You may wish to include a feature which can timeout manually here. Just remember if you do that, do not destroy the dllstruct for the ping ;   because likelly the ping thread will still write to it when it's done.  You will have to wait for that to happen before you destroy it.         $pingID += 1     WEnd EndFunc Func encodeIP($ip_addr)     Local $ip_addr_temp = $ip_addr     If Not _isIP($ip_addr) Then $ip_addr = TCPNameToIP($ip_addr)         If Not _isIP($ip_addr) Then         ConsoleWrite($ip_addr_temp & " is not a valid IP Address. If you supplied a hostname ensure DNS is available." & @CRLF)         Return 0     EndIf     Return getHexIP($ip_addr) EndFunc Func getHexIP($ip_addr)     Return Hex(_getIPOctet($ip_addr,4),2) & Hex(_getIPOctet($ip_addr,3),2) & Hex(_getIPOctet($ip_addr,2),2) & Hex(_getIPOctet($ip_addr,1),2) EndFunc Func LibLoad($lpLibFileName)     Local $LibHandle = DllCall($hkernel32Dll, "int", "LoadLibraryA", "str", $lpLibFileName)     Return $LibHandle[0] EndFunc Func LibFree($DllHandle)     Local $LibFreed = DllCall($hkernel32Dll, "int", "FreeLibrary", "int", $DllHandle)     return $LibFreed[0] EndFunc Func GetProcAddress( $hModule, $lpProcName)     Local $ProcessAddy = DllCall($hkernel32Dll,"int","GetProcAddress","int",$hModule,"str",$lpProcName)     Return $ProcessAddy[0] EndFunc Func SwapEndian($hex)     ;trancexx     Return Hex(Binary($hex)) EndFunc Func _getIPOctet($ip_addr,$octet=1)     Switch $octet         Case 1         Return Int(StringMid($ip_addr,1,StringInStr($ip_addr,".")))     Case 4         Return Int(StringMid($ip_addr,StringInStr($ip_addr,".",0,3)+1))     Case Else         Return Int(StringMid($ip_addr,StringInStr($ip_addr,".",0,$octet - 1)+1,StringInStr($ip_addr,".",0,$octet)+1))     EndSwitch EndFunc Func _isIP($text)     Return StringRegExp($text, "(((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9]?[0-9]))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9]?[0-9]))") EndFunc Func _Exit()     TCPShutdown()     LibFree($hICMPDll)     DllClose($hkernel32Dll)     Exit EndFunc

I tryed it with HOSTNAMES (instead of ip addresses)  from my network.

But when the computer is offline, the script is pretty slow. It comes from the TCPNameToIP() function and, I suppose, the getaddrinfo Windows function behind.

It seems there is no timeout parameter to pass to this function. So my question is : Is there a way to add a timeout ?


Viewing all articles
Browse latest Browse all 12506

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>