Bumping manifests a=b2g-bump
[gecko.git] / netwerk / test / TestDNSDaemon.cpp
blobfa347aa0c7e0b139eeb84fe84765ea0ebfbff96f
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include <stdio.h>
7 #include <sys/types.h>
8 #include <sys/socket.h>
9 #include <sys/un.h>
10 #include <unistd.h>
11 #include <errno.h>
13 #if defined(AIX) || defined(__linux)
14 #include <sys/select.h> // for fd_set
15 #endif
17 #if defined(__linux)
18 // Didn't find gettdtablehi() or gettdtablesize() on linux. Using FD_SETSIZE
19 #define getdtablehi() FD_SETSIZE
20 #else
21 #define getdtablehi() getdtablesize()
23 // If you find a system doesn't have getdtablesize try #define getdtablesize
24 // to FD_SETSIZE. And if you encounter a system that doesn't even have
25 // FD_SETSIZE, just grab your ankles and use 255.
26 #endif
29 #include "nspr.h"
30 #include "nsCRT.h"
31 #include "unix_dns.h"
33 struct sockaddr_un unix_addr;
35 int async_dns_lookup(char* hostName)
37 fprintf(stderr, "start async_dns_lookup\n");
38 int socket_fd = socket(PF_UNIX, SOCK_STREAM, 0);
39 if (socket_fd == -1) {
40 fprintf(stderr, "socket returned error.\n");
41 return -1;
44 unix_addr.sun_family = AF_UNIX;
45 strcpy(unix_addr.sun_path, DNS_SOCK_NAME);
47 int err = connect(socket_fd,(struct sockaddr*)&unix_addr, sizeof(unix_addr));
48 if (err == -1) {
49 fprintf(stderr, "connect failed (errno = %d).\n",errno);
50 close(socket_fd);
51 return -1;
54 char buf[256];
55 strcpy(buf, "lookup: ");
56 strcpy(&buf[8], hostName);
58 err = send(socket_fd, buf, strlen(buf)+1, 0);
59 if (err < 0)
60 fprintf(stderr, "send(%s) returned error (errno=%d).\n",buf, errno);
62 // receive 4 byte ID
63 err = recv(socket_fd, buf, 256, 0);
64 if (err < 0)
65 fprintf(stderr, "recv() returned error (errno=%d).\n", errno);
66 else
68 // printf("recv() returned %d bytes.");
69 int id = *(int *)buf;
70 fprintf(stderr, "id: %d\n", id);
73 return socket_fd;
76 static char *
77 string_trim(char *s)
79 char *s2;
80 if (!s) return 0;
81 s2 = s + strlen(s) - 1;
82 while (s2 > s && (*s2 == '\n' || *s2 == '\r' || *s2 == ' ' || *s2 == '\t'))
83 *s2-- = 0;
84 while (*s == ' ' || *s == '\t' || *s == '\n' || *s == '\r')
85 s++;
86 return s;
89 hostent *
90 bytesToHostent(char *buf)
92 int i;
93 // int size = 0;
94 int len, aliasCount, addressCount;
95 int addrtype, addrlength;
96 char* p = buf;
97 char s[1024];
99 len = *(int *)p; // length of name
100 p += sizeof(int); // advance past name length
102 memcpy(s, p, len); s[len] = 0;
103 fprintf(stderr, "hostname: %s\n", s);
105 p += len; // advance past name
106 aliasCount = *(int *)p; // number of aliases
107 p += sizeof(int); // advance past alias count
109 for (i=0; i<aliasCount; i++) {
110 len = *(int *)p; // length of alias name
111 p += sizeof(int); // advance past alias name length
113 memcpy(s, p, len); s[len] = 0;
114 fprintf(stderr, "alias: %s\n", s);
116 p += len; // advance past alias name
119 addrtype = *(int *)p;
121 fprintf(stderr, "addrtype: %d\n", addrtype);
123 p += sizeof(int);
124 addrlength = *(int *)p;
126 fprintf(stderr, "addrlength: %d\n", addrlength);
128 p += sizeof(int);
129 addressCount = *(int *)p;
130 p += sizeof(int);
132 for (i=0; i<addressCount; i++) {
133 len = *(int *)p;
134 p += sizeof(int);
136 fprintf(stderr, "addr len: %d\n", len);
137 fprintf(stderr, "addr : %x\n", *(int *)p);
139 p += len;
142 // size = p - buf;
143 // size += 1 + aliasCount;
144 return 0;
148 main(int argc, char* argv[])
150 PRStatus status;
152 // launch daemon
153 printf("### launch daemon...\n");
155 PRProcessAttr *attributes = PR_NewProcessAttr();
156 if (attributes == nullptr) {
157 printf("PR_NewProcessAttr() failed.\n");
158 return -1;
161 PRProcess *daemon = PR_CreateProcess("nsDnsAsyncLookup", nullptr, nullptr, attributes);
162 if (daemon == nullptr) {
163 printf("PR_CreateProcess failed.\n");
164 } else {
165 // status = PR_DetachProcess(daemon);
166 //if (status != 0)
167 // printf("PR_DetachProcess returned %d\n", status);
168 //daemon = nullptr;
171 PR_DestroyProcessAttr(attributes);
173 // create socket and connect to daemon
174 int socket_fd = 0;
177 bool notDone = true;
178 char buf[1024];
180 while(notDone) {
181 int status = 0;
182 fd_set fdset;
184 FD_ZERO(&fdset);
185 FD_SET(fileno(stdin), &fdset);
186 if (socket_fd > 0)
187 FD_SET(socket_fd, &fdset);
189 status = select(getdtablehi(), &fdset, 0, 0, 0);
190 if (status <= 0)
192 fprintf(stderr, "%s: select() returned %d\n", argv[0], status);
193 exit(-1);
196 // which fd is set?
198 if (FD_ISSET(fileno(stdin), &fdset))
200 char *line = fgets(buf, sizeof(buf)-1, stdin);
201 line = string_trim(line);
203 if(!strcmp(line, "quit") || !strcmp(line, "exit"))
205 fprintf(stderr, "bye now.\n");
206 notDone = false;
208 else if (!strncmp(line, "abort ", 6))
210 // abort id
212 else if (strchr(line, ' ') || strchr(line, '\t'))
214 fprintf(stderr, "%s: unrecognized command %s.\n", argv[0], line);
216 else
218 fprintf(stderr, "%s: looking up %s...\n", argv[0], line);
219 // initiate dns lookup
220 socket_fd = async_dns_lookup(line);
224 if (socket_fd && FD_ISSET(socket_fd, &fdset))
226 // read from socket, parse results
227 int size = read(socket_fd, buf, 1024);
228 if (size > 0)
230 // parse buffer into hostent
231 char *p = buf;
232 fprintf(stderr, "bytes read: %d\n", size);
233 fprintf(stderr, "response code: %d\n", *(int *)p);
234 p += sizeof(int);
236 for (int i=0; i < size; i++) {
237 if (!(i%8))
238 fprintf(stderr, "\n");
239 fprintf(stderr, "%2.2x ",(unsigned char)buf[i]);
241 fprintf(stderr, "\n");
242 hostent *h;
243 h = bytesToHostent(p);
245 close(socket_fd);
246 socket_fd = 0;
250 return 0;
254 buffer
256 int nameLen;
258 if (nameLen > 0)
259 char [nameLen+1] name
261 int aliasCount
262 for each alias
263 int aliasNameLen
264 char [aliasNameLen+1] aliasName
266 int h_addrtype
267 int h_length
268 int addrCount
269 for each addr
270 char[h_length] addr