modified: myjupyterlab.sh
[GalaxyCodeBases.git] / etc / Windows / vlmcsd_old_vancepym / dns_srv.c
blobccf2cd0821017ae4e564aeddb34308f52da822fe
1 /*
2 * dns_srv.c
4 * This file contains the code for KMS SRV record lookup in DNS (_vlmcs._tcp.example.com IN SRV 0 0 1688 mykms.example.com)
6 */
8 #ifndef CONFIG
9 #define CONFIG "config.h"
10 #endif // CONFIG
11 #include CONFIG
13 #ifndef NO_DNS
15 #include "dns_srv.h"
17 #include <string.h>
18 #include <stdio.h>
19 #ifndef _WIN32
20 #include <signal.h>
21 #include <unistd.h>
22 #include <fcntl.h>
23 #include <errno.h>
24 #include <netdb.h>
25 //#ifndef DNS_PARSER_INTERNAL
26 #if __ANDROID__
27 #include <netinet/in.h>
28 #include "nameser.h"
29 #include "resolv.h"
30 #else // other Unix non-Android
31 #include <netinet/in.h>
32 #include <arpa/nameser.h>
33 #include <resolv.h>
34 #endif // other Unix non-Android
35 //#endif // DNS_PARSER_INTERNAL
36 #else // WIN32
37 #include <windns.h>
38 #endif // WIN32
40 #include "helpers.h"
41 #include "output.h"
42 #include "endian.h"
44 #if defined(DNS_PARSER_INTERNAL) && !defined(_WIN32)
46 #include "ns_name.h"
47 #include "ns_parse.h"
49 // Define macros to redirect DNS parser functions to internal versions
51 #undef ns_msg
52 #undef ns_initparse
53 #undef ns_parserr
54 #undef ns_rr
55 #undef ns_name_uncompress
56 #undef ns_msg_base
57 #undef ns_msg_end
58 #undef ns_rr_rdata
59 #undef ns_rr_type
60 #undef ns_msg_count
61 #undef ns_rr_class
62 #undef ns_s_an
63 #define ns_msg ns_msg_vlmcsd
64 #define ns_initparse ns_initparse_vlmcsd
65 #define ns_parserr ns_parserr_vlmcsd
66 #define ns_rr ns_rr_vlmcsd
67 #define ns_name_uncompress ns_name_uncompress_vlmcsd
68 #define ns_msg_base ns_msg_base_vlmcsd
69 #define ns_msg_end ns_msg_end_vlmcsd
70 #define ns_rr_rdata ns_rr_rdata_vlmcsd
71 #define ns_rr_type ns_rr_type_vlmcsd
72 #define ns_msg_count ns_msg_count_vlmcsd
73 #define ns_rr_class ns_rr_class_vlmcsd
74 #define ns_s_an ns_s_an_vlmcsd
76 #ifndef NS_MAXLABEL
77 #define NS_MAXLABEL 63
78 #endif
80 #endif // defined(DNS_PARSER_INTERNAL) && !defined(_WIN32)
83 //TODO: maybe move to helpers.c
84 static unsigned int isqrt(unsigned int n)
86 unsigned int c = 0x8000;
87 unsigned int g = 0x8000;
89 for(;;)
91 if(g*g > n)
92 g ^= c;
94 c >>= 1;
96 if(c == 0) return g;
98 g |= c;
104 * Compare function for qsort to sort SRV records by priority and weight
105 * random_weight must be product of weight from SRV record and square root of a random number
107 static int kmsServerListCompareFunc1(const void* a, const void* b)
109 if ( !a && !b) return 0;
110 if ( a && !b) return -1;
111 if ( !a && b) return 1;
113 int priority_order = (int)((*(kms_server_dns_ptr*)a)->priority) - ((int)(*(kms_server_dns_ptr*)b)->priority);
115 if (priority_order) return priority_order;
117 return (int)((*(kms_server_dns_ptr*)b)->random_weight) - ((int)(*(kms_server_dns_ptr*)a)->random_weight);
120 /* Sort resulting SRV records */
121 void sortSrvRecords(kms_server_dns_ptr* serverlist, const int answers)
123 int i;
125 for (i = 0; i < answers; i++)
127 serverlist[i]->random_weight = (rand32() % 256) * isqrt(serverlist[i]->weight * 1000);
130 qsort(serverlist, answers, sizeof(kms_server_dns_ptr), kmsServerListCompareFunc1);
134 #define RECEIVE_BUFFER_SIZE 2048
135 #ifndef _WIN32 // UNIX resolver
138 * Retrieves a raw DNS answer (a buffer of what came over the net)
139 * Result must be parsed
141 static int getDnsRawAnswer(const char *restrict query, unsigned char** receive_buffer)
143 if (res_init() < 0)
145 errorout("Cannot initialize resolver: %s", strerror(errno));
146 return 0;
149 //if(!(*receive_buffer = (unsigned char*)malloc(RECEIVE_BUFFER_SIZE))) OutOfMemory();
150 *receive_buffer = (unsigned char*)vlmcsd_malloc(RECEIVE_BUFFER_SIZE);
152 int bytes_received;
154 if (*query == '.')
156 # if __ANDROID__ || __GLIBC__ /* including __UCLIBC__*/ || __APPLE__ || __CYGWIN__ || __FreeBSD__ || __NetBSD__ || __DragonFly__ || __OpenBSD__ || __sun__
157 bytes_received = res_querydomain("_vlmcs._tcp", query + 1, ns_c_in, ns_t_srv, *receive_buffer, RECEIVE_BUFFER_SIZE);
158 # else
159 char* querystring = (char*)alloca(strlen(query) + 12);
160 strcpy(querystring, "_vlmcs._tcp");
161 strcat(querystring, query);
162 bytes_received = res_query(querystring, ns_c_in, ns_t_srv, *receive_buffer, RECEIVE_BUFFER_SIZE);
163 # endif
165 else
167 bytes_received = res_search("_vlmcs._tcp", ns_c_in, ns_t_srv, *receive_buffer, RECEIVE_BUFFER_SIZE);
170 if (bytes_received < 0)
172 errorout("Fatal: DNS query to %s%s failed: %s\n", "_vlmcs._tcp", *query == '.' ? query : "", hstrerror(h_errno));
173 return 0;
176 return bytes_received;
180 * Retrieves an unsorted array of SRV records (Unix / Posix)
182 int getKmsServerList(kms_server_dns_ptr** serverlist, const char *restrict query)
184 unsigned char* receive_buffer;
185 *serverlist = NULL;
187 int bytes_received = getDnsRawAnswer(query, &receive_buffer);
189 if (bytes_received == 0) return 0;
191 ns_msg msg;
193 if (ns_initparse(receive_buffer, bytes_received, &msg) < 0)
195 errorout("Fatal: Incorrect DNS response: %s\n", strerror(errno));
196 free(receive_buffer);
197 return 0;
200 uint16_t i, answers = ns_msg_count(msg, ns_s_an);
201 //if(!(*serverlist = (kms_server_dns_ptr*)malloc(answers * sizeof(kms_server_dns_ptr)))) OutOfMemory();
202 *serverlist = (kms_server_dns_ptr*)malloc(answers * sizeof(kms_server_dns_ptr));
204 memset(*serverlist, 0, answers * sizeof(kms_server_dns_ptr));
206 for (i = 0; i < answers; i++)
208 ns_rr rr;
210 if (ns_parserr(&msg, ns_s_an, i, &rr) < 0)
212 errorout("Warning: Error in DNS resource record: %s\n", strerror(errno));
213 continue;
216 if (ns_rr_type(rr) != ns_t_srv)
218 errorout("Warning: DNS server returned non-SRV record\n");
219 continue;
222 if (ns_rr_class(rr) != ns_c_in)
224 errorout("Warning: DNS server returned non-IN class record\n");
225 continue;
228 dns_srv_record_ptr srvrecord = (dns_srv_record_ptr)ns_rr_rdata(rr);
229 kms_server_dns_ptr kms_server = (kms_server_dns_ptr)vlmcsd_malloc(sizeof(kms_server_dns_t));
231 (*serverlist)[i] = kms_server;
233 if (ns_name_uncompress(ns_msg_base(msg), ns_msg_end(msg), srvrecord->name, kms_server->serverName, sizeof(kms_server->serverName)) < 0)
235 errorout("Warning: No valid DNS name returned in SRV record: %s\n", strerror(errno));
236 continue;
239 sprintf(kms_server->serverName + strlen(kms_server->serverName), ":%hu", GET_UA16BE(&srvrecord->port));
240 kms_server->priority = GET_UA16BE(&srvrecord->priority);
241 kms_server->weight = GET_UA16BE(&srvrecord->weight);
245 free(receive_buffer);
246 return answers;
249 #else // WIN32 (Windows Resolver)
252 * Retrieves an unsorted array of SRV records (Windows)
254 int getKmsServerList(kms_server_dns_ptr** serverlist, const char *const restrict query)
256 # define MAX_DNS_NAME_SIZE 254
257 *serverlist = NULL;
258 PDNS_RECORD receive_buffer;
259 char dnsDomain[MAX_DNS_NAME_SIZE];
260 char FqdnQuery[MAX_DNS_NAME_SIZE];
261 DWORD size = MAX_DNS_NAME_SIZE;
262 DNS_STATUS result;
263 int answers = 0;
264 PDNS_RECORD dns_iterator;
266 if (*query == '-')
268 if (!GetComputerNameExA(ComputerNamePhysicalDnsDomain, dnsDomain, &size))
270 errorout("Fatal: Could not determine computer's DNS name: %s\n", vlmcsd_strerror(GetLastError()));
271 return 0;
274 strcpy(FqdnQuery, "_vlmcs._tcp.");
275 strncat(FqdnQuery, dnsDomain, MAX_DNS_NAME_SIZE - 12);
277 else
279 strcpy(FqdnQuery, "_vlmcs._tcp");
280 strncat(FqdnQuery, query, MAX_DNS_NAME_SIZE - 11);
283 if ((result = DnsQuery_UTF8(FqdnQuery, DNS_TYPE_SRV, 0, NULL, &receive_buffer, NULL)) != 0)
285 errorout("Fatal: DNS query to %s failed: %s\n", FqdnQuery, vlmcsd_strerror(result));
286 return 0;
289 for (dns_iterator = receive_buffer; dns_iterator; dns_iterator = dns_iterator->pNext)
291 if (dns_iterator->Flags.S.Section != 1) continue;
293 if (dns_iterator->wType != DNS_TYPE_SRV)
295 errorout("Warning: DNS server returned non-SRV record\n");
296 continue;
299 answers++;
302 *serverlist = (kms_server_dns_ptr*)vlmcsd_malloc(answers * sizeof(kms_server_dns_ptr));
304 for (answers = 0, dns_iterator = receive_buffer; dns_iterator; dns_iterator = dns_iterator->pNext)
306 if (dns_iterator->wType != DNS_TYPE_SRV) continue;
308 kms_server_dns_ptr kms_server = (kms_server_dns_ptr)vlmcsd_malloc(sizeof(kms_server_dns_t));
310 memset(kms_server, 0, sizeof(kms_server_dns_t));
312 snprintf(kms_server->serverName, sizeof(kms_server->serverName), "%s:%hu", dns_iterator->Data.SRV.pNameTarget, dns_iterator->Data.SRV.wPort);
313 kms_server->priority = dns_iterator->Data.SRV.wPriority;
314 kms_server->weight = dns_iterator->Data.SRV.wWeight;
316 (*serverlist)[answers++] = kms_server;
319 //sortSrvRecords(*serverlist, answers, NoSrvRecordPriority);
321 DnsRecordListFree(receive_buffer, DnsFreeRecordList);
323 return answers;
324 # undef MAX_DNS_NAME_SIZE
326 #endif // _WIN32
327 #undef RECEIVE_BUFFER_SIZE
328 #endif // NO_DNS