@@ -746,7 +746,79 @@ pub fn getAddressList(allocator: mem.Allocator, name: []const u8, port: u16) !*A
746746 const arena = result .arena .allocator ();
747747 errdefer result .deinit ();
748748
749- if (builtin .target .os .tag == .windows or builtin .link_libc ) {
749+ if (builtin .target .os .tag == .windows ) {
750+ const name_c = try std .cstr .addNullByte (allocator , name );
751+ defer allocator .free (name_c );
752+
753+ const port_c = try std .fmt .allocPrintZ (allocator , "{}" , .{port });
754+ defer allocator .free (port_c );
755+
756+ const ws2_32 = os .windows .ws2_32 ;
757+ const hints = os.addrinfo {
758+ .flags = ws2_32 .AI .NUMERICSERV ,
759+ .family = os .AF .UNSPEC ,
760+ .socktype = os .SOCK .STREAM ,
761+ .protocol = os .IPPROTO .TCP ,
762+ .canonname = null ,
763+ .addr = null ,
764+ .addrlen = 0 ,
765+ .next = null ,
766+ };
767+ var res : * os.addrinfo = undefined ;
768+ var first = true ;
769+ while (true ) {
770+ const rc = ws2_32 .getaddrinfo (name_c .ptr , port_c .ptr , & hints , & res );
771+ switch (@intToEnum (os .windows .ws2_32 .WinsockError , @intCast (u16 , rc ))) {
772+ @intToEnum (os .windows .ws2_32 .WinsockError , 0 ) = > break ,
773+ .WSATRY_AGAIN = > return error .TemporaryNameServerFailure ,
774+ .WSANO_RECOVERY = > return error .NameServerFailure ,
775+ .WSAEAFNOSUPPORT = > return error .AddressFamilyNotSupported ,
776+ .WSA_NOT_ENOUGH_MEMORY = > return error .OutOfMemory ,
777+ .WSAHOST_NOT_FOUND = > return error .UnknownHostName ,
778+ .WSATYPE_NOT_FOUND = > return error .ServiceUnavailable ,
779+ .WSAEINVAL = > unreachable ,
780+ .WSAESOCKTNOSUPPORT = > unreachable ,
781+ .WSANOTINITIALISED = > {
782+ if (! first ) return error .Unexpected ;
783+ first = false ;
784+ try os .windows .callWSAStartup ();
785+ continue ;
786+ },
787+ else = > | err | return os .windows .unexpectedWSAError (err ),
788+ }
789+ }
790+ defer ws2_32 .freeaddrinfo (res );
791+
792+ const addr_count = blk : {
793+ var count : usize = 0 ;
794+ var it : ? * os.addrinfo = res ;
795+ while (it ) | info | : (it = info .next ) {
796+ if (info .addr != null ) {
797+ count += 1 ;
798+ }
799+ }
800+ break :blk count ;
801+ };
802+ result .addrs = try arena .alloc (Address , addr_count );
803+
804+ var it : ? * os.addrinfo = res ;
805+ var i : usize = 0 ;
806+ while (it ) | info | : (it = info .next ) {
807+ const addr = info .addr orelse continue ;
808+ result .addrs [i ] = Address .initPosix (@alignCast (4 , addr ));
809+
810+ if (info .canonname ) | n | {
811+ if (result .canon_name == null ) {
812+ result .canon_name = try arena .dupe (u8 , mem .sliceTo (n , 0 ));
813+ }
814+ }
815+ i += 1 ;
816+ }
817+
818+ return result ;
819+ }
820+
821+ if (builtin .link_libc ) {
750822 const name_c = try std .cstr .addNullByte (allocator , name );
751823 defer allocator .free (name_c );
752824
@@ -765,19 +837,7 @@ pub fn getAddressList(allocator: mem.Allocator, name: []const u8, port: u16) !*A
765837 .next = null ,
766838 };
767839 var res : * os.addrinfo = undefined ;
768- const rc = sys .getaddrinfo (name_c .ptr , port_c .ptr , & hints , & res );
769- if (builtin .target .os .tag == .windows ) switch (@intToEnum (os .windows .ws2_32 .WinsockError , @intCast (u16 , rc ))) {
770- @intToEnum (os .windows .ws2_32 .WinsockError , 0 ) = > {},
771- .WSATRY_AGAIN = > return error .TemporaryNameServerFailure ,
772- .WSANO_RECOVERY = > return error .NameServerFailure ,
773- .WSAEAFNOSUPPORT = > return error .AddressFamilyNotSupported ,
774- .WSA_NOT_ENOUGH_MEMORY = > return error .OutOfMemory ,
775- .WSAHOST_NOT_FOUND = > return error .UnknownHostName ,
776- .WSATYPE_NOT_FOUND = > return error .ServiceUnavailable ,
777- .WSAEINVAL = > unreachable ,
778- .WSAESOCKTNOSUPPORT = > unreachable ,
779- else = > | err | return os .windows .unexpectedWSAError (err ),
780- } else switch (rc ) {
840+ switch (sys .getaddrinfo (name_c .ptr , port_c .ptr , & hints , & res )) {
781841 @intToEnum (sys .EAI , 0 ) = > {},
782842 .ADDRFAMILY = > return error .HostLacksNetworkAddresses ,
783843 .AGAIN = > return error .TemporaryNameServerFailure ,
@@ -824,6 +884,7 @@ pub fn getAddressList(allocator: mem.Allocator, name: []const u8, port: u16) !*A
824884
825885 return result ;
826886 }
887+
827888 if (builtin .target .os .tag == .linux ) {
828889 const flags = std .c .AI .NUMERICSERV ;
829890 const family = os .AF .UNSPEC ;
0 commit comments