netwerk/test/TestDNSDaemon.cpp

Wed, 31 Dec 2014 06:55:46 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:46 +0100
changeset 1
ca08bd8f51b2
permissions
-rw-r--r--

Added tag TORBROWSER_REPLICA for changeset 6474c204b198

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

mercurial