1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/netwerk/test/TestDNSDaemon.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,274 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include <stdio.h> 1.10 +#include <sys/types.h> 1.11 +#include <sys/socket.h> 1.12 +#include <sys/un.h> 1.13 +#include <unistd.h> 1.14 +#include <errno.h> 1.15 + 1.16 +#if defined(AIX) || defined(__linux) 1.17 +#include <sys/select.h> // for fd_set 1.18 +#endif 1.19 + 1.20 +#if defined(__linux) 1.21 +// Didn't find gettdtablehi() or gettdtablesize() on linux. Using FD_SETSIZE 1.22 +#define getdtablehi() FD_SETSIZE 1.23 +#else 1.24 +#define getdtablehi() getdtablesize() 1.25 + 1.26 +// If you find a system doesn't have getdtablesize try #define getdtablesize 1.27 +// to FD_SETSIZE. And if you encounter a system that doesn't even have 1.28 +// FD_SETSIZE, just grab your ankles and use 255. 1.29 +#endif 1.30 + 1.31 + 1.32 +#include "nspr.h" 1.33 +#include "nsCRT.h" 1.34 +#include "unix_dns.h" 1.35 + 1.36 +struct sockaddr_un unix_addr; 1.37 + 1.38 +int async_dns_lookup(char* hostName) 1.39 +{ 1.40 + fprintf(stderr, "start async_dns_lookup\n"); 1.41 + int socket_fd = socket(PF_UNIX, SOCK_STREAM, 0); 1.42 + if (socket_fd == -1) { 1.43 + fprintf(stderr, "socket returned error.\n"); 1.44 + return -1; 1.45 + } 1.46 + 1.47 + unix_addr.sun_family = AF_UNIX; 1.48 + strcpy(unix_addr.sun_path, DNS_SOCK_NAME); 1.49 + 1.50 + int err = connect(socket_fd,(struct sockaddr*)&unix_addr, sizeof(unix_addr)); 1.51 + if (err == -1) { 1.52 + fprintf(stderr, "connect failed (errno = %d).\n",errno); 1.53 + close(socket_fd); 1.54 + return -1; 1.55 + } 1.56 + 1.57 + char buf[256]; 1.58 + strcpy(buf, "lookup: "); 1.59 + strcpy(&buf[8], hostName); 1.60 + 1.61 + err = send(socket_fd, buf, strlen(buf)+1, 0); 1.62 + if (err < 0) 1.63 + fprintf(stderr, "send(%s) returned error (errno=%d).\n",buf, errno); 1.64 + 1.65 + // receive 4 byte ID 1.66 + err = recv(socket_fd, buf, 256, 0); 1.67 + if (err < 0) 1.68 + fprintf(stderr, "recv() returned error (errno=%d).\n", errno); 1.69 + else 1.70 + { 1.71 + // printf("recv() returned %d bytes."); 1.72 + int id = *(int *)buf; 1.73 + fprintf(stderr, "id: %d\n", id); 1.74 + } 1.75 + 1.76 + return socket_fd; 1.77 +} 1.78 + 1.79 +static char * 1.80 +string_trim(char *s) 1.81 +{ 1.82 + char *s2; 1.83 + if (!s) return 0; 1.84 + s2 = s + strlen(s) - 1; 1.85 + while (s2 > s && (*s2 == '\n' || *s2 == '\r' || *s2 == ' ' || *s2 == '\t')) 1.86 + *s2-- = 0; 1.87 + while (*s == ' ' || *s == '\t' || *s == '\n' || *s == '\r') 1.88 + s++; 1.89 + return s; 1.90 +} 1.91 + 1.92 +hostent * 1.93 +bytesToHostent(char *buf) 1.94 +{ 1.95 + int i; 1.96 + // int size = 0; 1.97 + int len, aliasCount, addressCount; 1.98 + int addrtype, addrlength; 1.99 + char* p = buf; 1.100 + char s[1024]; 1.101 + 1.102 + len = *(int *)p; // length of name 1.103 + p += sizeof(int); // advance past name length 1.104 + 1.105 + memcpy(s, p, len); s[len] = 0; 1.106 + fprintf(stderr, "hostname: %s\n", s); 1.107 + 1.108 + p += len; // advance past name 1.109 + aliasCount = *(int *)p; // number of aliases 1.110 + p += sizeof(int); // advance past alias count 1.111 + 1.112 + for (i=0; i<aliasCount; i++) { 1.113 + len = *(int *)p; // length of alias name 1.114 + p += sizeof(int); // advance past alias name length 1.115 + 1.116 + memcpy(s, p, len); s[len] = 0; 1.117 + fprintf(stderr, "alias: %s\n", s); 1.118 + 1.119 + p += len; // advance past alias name 1.120 + } 1.121 + 1.122 + addrtype = *(int *)p; 1.123 + 1.124 + fprintf(stderr, "addrtype: %d\n", addrtype); 1.125 + 1.126 + p += sizeof(int); 1.127 + addrlength = *(int *)p; 1.128 + 1.129 + fprintf(stderr, "addrlength: %d\n", addrlength); 1.130 + 1.131 + p += sizeof(int); 1.132 + addressCount = *(int *)p; 1.133 + p += sizeof(int); 1.134 + 1.135 + for (i=0; i<addressCount; i++) { 1.136 + len = *(int *)p; 1.137 + p += sizeof(int); 1.138 + 1.139 + fprintf(stderr, "addr len: %d\n", len); 1.140 + fprintf(stderr, "addr : %x\n", *(int *)p); 1.141 + 1.142 + p += len; 1.143 + } 1.144 + 1.145 + // size = p - buf; 1.146 + // size += 1 + aliasCount; 1.147 + return 0; 1.148 +} 1.149 + 1.150 +int 1.151 +main(int argc, char* argv[]) 1.152 +{ 1.153 + PRStatus status; 1.154 + 1.155 + // launch daemon 1.156 + printf("### launch daemon...\n"); 1.157 + 1.158 + PRProcessAttr *attributes = PR_NewProcessAttr(); 1.159 + if (attributes == nullptr) { 1.160 + printf("PR_NewProcessAttr() failed.\n"); 1.161 + return -1; 1.162 + } 1.163 + 1.164 + PRProcess *daemon = PR_CreateProcess("nsDnsAsyncLookup", nullptr, nullptr, attributes); 1.165 + if (daemon == nullptr) { 1.166 + printf("PR_CreateProcess failed.\n"); 1.167 + } else { 1.168 + // status = PR_DetachProcess(daemon); 1.169 + //if (status != 0) 1.170 + // printf("PR_DetachProcess returned %d\n", status); 1.171 + //daemon = nullptr; 1.172 + } 1.173 + 1.174 + PR_DestroyProcessAttr(attributes); 1.175 + 1.176 + // create socket and connect to daemon 1.177 + int socket_fd = 0; 1.178 + 1.179 + 1.180 + bool notDone = true; 1.181 + char buf[1024]; 1.182 + 1.183 + while(notDone) { 1.184 + int status = 0; 1.185 + fd_set fdset; 1.186 + 1.187 + FD_ZERO(&fdset); 1.188 + FD_SET(fileno(stdin), &fdset); 1.189 + if (socket_fd > 0) 1.190 + FD_SET(socket_fd, &fdset); 1.191 + 1.192 + status = select(getdtablehi(), &fdset, 0, 0, 0); 1.193 + if (status <= 0) 1.194 + { 1.195 + fprintf(stderr, "%s: select() returned %d\n", argv[0], status); 1.196 + exit(-1); 1.197 + } 1.198 + 1.199 + // which fd is set? 1.200 + 1.201 + if (FD_ISSET(fileno(stdin), &fdset)) 1.202 + { 1.203 + char *line = fgets(buf, sizeof(buf)-1, stdin); 1.204 + line = string_trim(line); 1.205 + 1.206 + if(!strcmp(line, "quit") || !strcmp(line, "exit")) 1.207 + { 1.208 + fprintf(stderr, "bye now.\n"); 1.209 + notDone = false; 1.210 + } 1.211 + else if (!strncmp(line, "abort ", 6)) 1.212 + { 1.213 + // abort id 1.214 + } 1.215 + else if (strchr(line, ' ') || strchr(line, '\t')) 1.216 + { 1.217 + fprintf(stderr, "%s: unrecognized command %s.\n", argv[0], line); 1.218 + } 1.219 + else 1.220 + { 1.221 + fprintf(stderr, "%s: looking up %s...\n", argv[0], line); 1.222 + // initiate dns lookup 1.223 + socket_fd = async_dns_lookup(line); 1.224 + } 1.225 + } 1.226 + 1.227 + if (socket_fd && FD_ISSET(socket_fd, &fdset)) 1.228 + { 1.229 + // read from socket, parse results 1.230 + int size = read(socket_fd, buf, 1024); 1.231 + if (size > 0) 1.232 + { 1.233 + // parse buffer into hostent 1.234 + char *p = buf; 1.235 + fprintf(stderr, "bytes read: %d\n", size); 1.236 + fprintf(stderr, "response code: %d\n", *(int *)p); 1.237 + p += sizeof(int); 1.238 + 1.239 + for (int i=0; i < size; i++) { 1.240 + if (!(i%8)) 1.241 + fprintf(stderr, "\n"); 1.242 + fprintf(stderr, "%2.2x ",(unsigned char)buf[i]); 1.243 + } 1.244 + fprintf(stderr, "\n"); 1.245 + hostent *h; 1.246 + h = bytesToHostent(p); 1.247 + } 1.248 + close(socket_fd); 1.249 + socket_fd = 0; 1.250 + } 1.251 + } 1.252 + 1.253 + return 0; 1.254 +} 1.255 + 1.256 +/* 1.257 +buffer 1.258 + 1.259 +int nameLen; 1.260 + 1.261 +if (nameLen > 0) 1.262 + char [nameLen+1] name 1.263 + 1.264 +int aliasCount 1.265 +for each alias 1.266 + int aliasNameLen 1.267 + char [aliasNameLen+1] aliasName 1.268 + 1.269 +int h_addrtype 1.270 +int h_length 1.271 +int addrCount 1.272 +for each addr 1.273 + char[h_length] addr 1.274 + 1.275 + 1.276 + 1.277 +*/