github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/bind/dns_ios.go (about) 1 // Copyright 2017 Keybase, Inc. All rights reserved. Use of 2 // this source code is governed by the included BSD license. 3 // 4 //go:build ios 5 // +build ios 6 7 package keybase 8 9 /* 10 #cgo LDFLAGS: -lresolv 11 #include <stdlib.h> 12 #include <resolv.h> 13 #include <dns.h> 14 #include <arpa/inet.h> 15 #include <ifaddrs.h> 16 #include <string.h> 17 18 typedef struct _dnsRes { 19 char** srvs; 20 int length; 21 } dnsRes; 22 23 dnsRes ios_getDNSServers() { 24 res_state res = malloc(sizeof(struct __res_state)); 25 int result = res_ninit(res); 26 dnsRes dnsSrvs; 27 dnsSrvs.length = 0; 28 if (result == 0 && res->nscount < 1024) { 29 union res_9_sockaddr_union *addr_union = malloc(res->nscount * sizeof(union res_9_sockaddr_union)); 30 res_getservers(res, addr_union, res->nscount); 31 32 dnsSrvs.length = res->nscount; 33 dnsSrvs.srvs = (char**) malloc(sizeof(char*)*res->nscount); 34 for (int i = 0; i < res->nscount; i++) { 35 if (addr_union[i].sin.sin_family == AF_INET) { 36 // free()'d in Go below 37 char* ip = (char*) malloc(INET_ADDRSTRLEN); 38 inet_ntop(AF_INET, &(addr_union[i].sin.sin_addr), ip, INET_ADDRSTRLEN); 39 dnsSrvs.srvs[i] = ip; 40 } else if (addr_union[i].sin6.sin6_family == AF_INET6) { 41 // free()'d in Go below 42 char* ip = (char*) malloc(INET6_ADDRSTRLEN); 43 inet_ntop(AF_INET6, &(addr_union[i].sin6.sin6_addr), ip, INET6_ADDRSTRLEN); 44 dnsSrvs.srvs[i] = ip; 45 } else { 46 // free()'d in Go below 47 dnsSrvs.srvs[i] = strdup("0.0.0.0"); 48 } 49 } 50 free(addr_union); 51 } 52 res_ndestroy(res); 53 free(res); 54 return dnsSrvs; 55 } 56 */ 57 import "C" 58 import "unsafe" 59 60 func getDNSServers() (res []string) { 61 dnsRes := C.ios_getDNSServers() 62 length := dnsRes.length 63 if length == 0 { 64 return res 65 } 66 67 csrvs := dnsRes.srvs 68 srvSlice := (*[1024]*C.char)(unsafe.Pointer(csrvs))[:length:length] 69 for _, csrv := range srvSlice { 70 res = append(res, C.GoString(csrv)) 71 C.free(unsafe.Pointer(csrv)) 72 } 73 C.free(unsafe.Pointer(csrvs)) 74 return res 75 }