github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/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  }