Wed, 31 Dec 2014 06:55:46 +0100
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 | */ |