| ... | ... | @@ -347,6 +347,7 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !* |
| 347 | 347 | errdefer result.arena.deinit(); |
| 348 | 348 | |
| 349 | 349 | if (builtin.link_libc) { |
| 350 | const c = std.c; |
| 350 | 351 | const name_c = try std.cstr.addNullByte(allocator, name); |
| 351 | 352 | defer allocator.free(name_c); |
| 352 | 353 | |
| ... | ... | @@ -354,7 +355,7 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !* |
| 354 | 355 | defer allocator.free(port_c); |
| 355 | 356 | |
| 356 | 357 | const hints = os.addrinfo{ |
| 357 | | .flags = os.AI_NUMERICSERV, |
| 358 | .flags = c.AI_NUMERICSERV, |
| 358 | 359 | .family = os.AF_UNSPEC, |
| 359 | 360 | .socktype = os.SOCK_STREAM, |
| 360 | 361 | .protocol = os.IPPROTO_TCP, |
| ... | ... | @@ -366,17 +367,17 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !* |
| 366 | 367 | var res: *os.addrinfo = undefined; |
| 367 | 368 | switch (os.system.getaddrinfo(name_c.ptr, port_c.ptr, &hints, &res)) { |
| 368 | 369 | 0 => {}, |
| 369 | | os.EAI_ADDRFAMILY => return error.HostLacksNetworkAddresses, |
| 370 | | os.EAI_AGAIN => return error.TemporaryNameServerFailure, |
| 371 | | os.EAI_BADFLAGS => unreachable, // Invalid hints |
| 372 | | os.EAI_FAIL => return error.NameServerFailure, |
| 373 | | os.EAI_FAMILY => return error.AddressFamilyNotSupported, |
| 374 | | os.EAI_MEMORY => return error.OutOfMemory, |
| 375 | | os.EAI_NODATA => return error.HostLacksNetworkAddresses, |
| 376 | | os.EAI_NONAME => return error.UnknownName, |
| 377 | | os.EAI_SERVICE => return error.ServiceUnavailable, |
| 378 | | os.EAI_SOCKTYPE => unreachable, // Invalid socket type requested in hints |
| 379 | | os.EAI_SYSTEM => switch (os.errno(-1)) { |
| 370 | c.EAI_ADDRFAMILY => return error.HostLacksNetworkAddresses, |
| 371 | c.EAI_AGAIN => return error.TemporaryNameServerFailure, |
| 372 | c.EAI_BADFLAGS => unreachable, // Invalid hints |
| 373 | c.EAI_FAIL => return error.NameServerFailure, |
| 374 | c.EAI_FAMILY => return error.AddressFamilyNotSupported, |
| 375 | c.EAI_MEMORY => return error.OutOfMemory, |
| 376 | c.EAI_NODATA => return error.HostLacksNetworkAddresses, |
| 377 | c.EAI_NONAME => return error.UnknownName, |
| 378 | c.EAI_SERVICE => return error.ServiceUnavailable, |
| 379 | c.EAI_SOCKTYPE => unreachable, // Invalid socket type requested in hints |
| 380 | c.EAI_SYSTEM => switch (os.errno(-1)) { |
| 380 | 381 | else => |e| return os.unexpectedErrno(e), |
| 381 | 382 | }, |
| 382 | 383 | else => unreachable, |
| ... | ... | @@ -485,6 +486,9 @@ fn linuxLookupName( |
| 485 | 486 | }); |
| 486 | 487 | if (cnt == 0 and (flags & os.AI_NUMERICHOST) == 0) { |
| 487 | 488 | cnt = try linuxLookupNameFromHosts(buf, canon_buf, canon_len, name, family); |
| 489 | if (cnt == 0) { |
| 490 | cnt = try linuxLookupNameFromDnsSearch(buf, canon_buf, canon_len, name, family); |
| 491 | } |
| 488 | 492 | } |
| 489 | 493 | } else { |
| 490 | 494 | canon_len.* = 0; |
| ... | ... | @@ -641,3 +645,52 @@ pub fn isValidHostName(hostname: []const u8) bool { |
| 641 | 645 | } |
| 642 | 646 | return true; |
| 643 | 647 | } |
| 648 | |
| 649 | fn linuxLookupNameFromDnsSearch( |
| 650 | buf: []LookupAddr, |
| 651 | canon_buf: []u8, |
| 652 | canon_len: *usize, |
| 653 | name: []const u8, |
| 654 | family: i32, |
| 655 | ) !usize { |
| 656 | var search: [256]u8 = undefined; |
| 657 | const resolv_conf = try getResolvConf(&search); |
| 658 | |
| 659 | // Count dots, suppress search when >=ndots or name ends in |
| 660 | // a dot, which is an explicit request for global scope. |
| 661 | //var dots: usize = 0; |
| 662 | //for (name) |byte| { |
| 663 | // if (byte == '.') dots += 1; |
| 664 | //} |
| 665 | |
| 666 | //if (dots >= conf.ndots || name[l-1]=='.') *search = 0; |
| 667 | |
| 668 | //// Strip final dot for canon, fail if multiple trailing dots. |
| 669 | //if (name[l-1]=='.') l--; |
| 670 | //if (!l || name[l-1]=='.') return EAI_NONAME; |
| 671 | |
| 672 | //// This can never happen; the caller already checked length. |
| 673 | //if (l >= 256) return EAI_NONAME; |
| 674 | |
| 675 | //// Name with search domain appended is setup in canon[]. This both |
| 676 | //// provides the desired default canonical name (if the requested |
| 677 | //// name is not a CNAME record) and serves as a buffer for passing |
| 678 | //// the full requested name to name_from_dns. |
| 679 | //memcpy(canon, name, l); |
| 680 | //canon[l] = '.'; |
| 681 | |
| 682 | //for (p=search; *p; p=z) { |
| 683 | // for (; isspace(*p); p++); |
| 684 | // for (z=p; *z && !isspace(*z); z++); |
| 685 | // if (z==p) break; |
| 686 | // if (z-p < 256 - l - 1) { |
| 687 | // memcpy(canon+l+1, p, z-p); |
| 688 | // canon[z-p+1+l] = 0; |
| 689 | // int cnt = name_from_dns(buf, canon, canon, family, &conf); |
| 690 | // if (cnt) return cnt; |
| 691 | // } |
| 692 | //} |
| 693 | |
| 694 | //canon[l] = 0; |
| 695 | //return name_from_dns(buf, canon, name, family, &conf); |
| 696 | } |