Download | Plain Text | No Line Numbers


  1. --- unbound-1.5.4.old/Makefile.in 2015-05-01 14:36:16.000000000 +0200
  2. +++ unbound-1.5.4/Makefile.in 2015-09-10 00:57:00.123513866 +0200
  3. @@ -110,7 +110,7 @@
  4. validator/validator.c validator/val_kcache.c validator/val_kentry.c \
  5. validator/val_neg.c validator/val_nsec3.c validator/val_nsec.c \
  6. validator/val_secalgo.c validator/val_sigcrypt.c \
  7. -validator/val_utils.c dns64/dns64.c $(CHECKLOCK_SRC) $(DNSTAP_SRC)
  8. +validator/val_utils.c dns64/dns64.c rewrite/rewrite.c $(CHECKLOCK_SRC) $(DNSTAP_SRC)
  9. COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \
  10. msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.lo \
  11. iter_donotq.lo iter_fwd.lo iter_hints.lo iter_priv.lo iter_resptype.lo \
  12. @@ -120,7 +120,7 @@
  13. random.lo rbtree.lo regional.lo rtt.lo dnstree.lo lookup3.lo lruhash.lo \
  14. slabhash.lo timehist.lo tube.lo winsock_event.lo autotrust.lo val_anchor.lo \
  15. validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
  16. -val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo \
  17. +val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo rewrite.lo \
  18. $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ)
  19. COMMON_OBJ=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \
  20. outside_network.lo
  21. @@ -715,7 +715,7 @@
  22. $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \
  23. $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/dns64/dns64.h \
  24. $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/validator/validator.h \
  25. - $(srcdir)/validator/val_utils.h
  26. + $(srcdir)/validator/val_utils.h $(srcdir)/rewrite/rewrite.h
  27. outbound_list.lo outbound_list.o: $(srcdir)/services/outbound_list.c config.h \
  28. $(srcdir)/services/outbound_list.h $(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h \
  29. $(srcdir)/util/netevent.h
  30. @@ -760,7 +760,7 @@
  31. $(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_kentry.h \
  32. $(srcdir)/validator/val_neg.h $(srcdir)/validator/autotrust.h $(srcdir)/libunbound/libworker.h \
  33. $(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/libunbound/unbound.h \
  34. - $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h
  35. + $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/rewrite/rewrite.h
  36. locks.lo locks.o: $(srcdir)/util/locks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h
  37. log.lo log.o: $(srcdir)/util/log.c config.h $(srcdir)/util/log.h $(srcdir)/util/locks.h $(srcdir)/sldns/sbuffer.h
  38. mini_event.lo mini_event.o: $(srcdir)/util/mini_event.c config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
  39. @@ -893,6 +893,12 @@
  40. $(srcdir)/util/storage/slabhash.h $(srcdir)/util/config_file.h $(srcdir)/util/fptr_wlist.h \
  41. $(srcdir)/util/netevent.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
  42. $(srcdir)/services/modstack.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h
  43. +rewrite.lo rewrite.o: $(srcdir)/rewrite/rewrite.c config.h $(srcdir)/rewrite/rewrite.h $(srcdir)/util/module.h \
  44. + $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h \
  45. + $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
  46. + $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h $(srcdir)/services/cache/dns.h $(srcdir)/util/config_file.h \
  47. + $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
  48. + $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/util/regional.h $(srcdir)/util/data/dname.h
  49. checklocks.lo checklocks.o: $(srcdir)/testcode/checklocks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
  50. $(srcdir)/testcode/checklocks.h
  51. dnstap.lo dnstap.o: $(srcdir)/dnstap/dnstap.c config.h $(srcdir)/sldns/sbuffer.h \
  52. --- unbound-1.5.4.old/services/modstack.c 2014-10-13 11:23:12.000000000 +0200
  53. +++ unbound-1.5.4/services/modstack.c 2015-09-07 02:52:32.379311303 +0200
  54. @@ -51,6 +51,8 @@
  55. #include "pythonmod/pythonmod.h"
  56. #endif
  57.  
  58. +#include "rewrite/rewrite.h"
  59. +
  60. /** count number of modules (words) in the string */
  61. static int
  62. count_modules(const char* s)
  63. @@ -123,6 +125,7 @@
  64. #endif
  65. "validator",
  66. "iterator",
  67. + "rewrite",
  68. NULL};
  69. return names;
  70. }
  71. @@ -141,6 +144,7 @@
  72. #endif
  73. &val_get_funcblock,
  74. &iter_get_funcblock,
  75. + &rewrite_get_funcblock,
  76. NULL};
  77. return fb;
  78. }
  79. --- unbound-1.5.4.old/util/config_file.c 2015-05-29 16:51:36.000000000 +0200
  80. +++ unbound-1.5.4/util/config_file.c 2015-09-08 16:56:47.429577213 +0200
  81. @@ -237,6 +237,7 @@
  82. cfg->ratelimit_for_domain = NULL;
  83. cfg->ratelimit_below_domain = NULL;
  84. cfg->ratelimit_factor = 10;
  85. + cfg->rewrite_domain = NULL;
  86. return cfg;
  87. error_exit:
  88. config_delete(cfg);
  89. @@ -740,6 +741,7 @@
  90. else O_DEC(opt, "ratelimit-factor", ratelimit_factor)
  91. else O_DEC(opt, "val-sig-skew-min", val_sig_skew_min)
  92. else O_DEC(opt, "val-sig-skew-max", val_sig_skew_max)
  93. + else O_LS2(opt, "rewrite-domain", rewrite_domain)
  94. /* not here:
  95. * outgoing-permit, outgoing-avoid - have list of ports
  96. * local-zone - zones and nodefault variables
  97. @@ -951,6 +953,7 @@
  98. free(cfg->dnstap_version);
  99. config_deldblstrlist(cfg->ratelimit_for_domain);
  100. config_deldblstrlist(cfg->ratelimit_below_domain);
  101. + config_deldblstrlist(cfg->rewrite_domain);
  102. free(cfg);
  103. }
  104.  
  105. --- unbound-1.5.4.old/util/config_file.h 2015-05-29 16:51:36.000000000 +0200
  106. +++ unbound-1.5.4/util/config_file.h 2015-09-08 16:56:54.600699034 +0200
  107. @@ -362,6 +362,8 @@
  108. struct config_str2list* ratelimit_below_domain;
  109. /** ratelimit factor, 0 blocks all, 10 allows 1/10 of traffic */
  110. int ratelimit_factor;
  111. + /** from/to-pairs of domains to rewrite */
  112. + struct config_str2list* rewrite_domain;
  113. };
  114.  
  115. /** from cfg username, after daemonise setup performed */
  116. --- unbound-1.5.4.old/util/configlexer.lex 2015-05-29 16:51:36.000000000 +0200
  117. +++ unbound-1.5.4/util/configlexer.lex 2015-09-09 01:22:48.646754172 +0200
  118. @@ -358,6 +358,7 @@
  119. ratelimit-for-domain{COLON} { YDVAR(2, VAR_RATELIMIT_FOR_DOMAIN) }
  120. ratelimit-below-domain{COLON} { YDVAR(2, VAR_RATELIMIT_BELOW_DOMAIN) }
  121. ratelimit-factor{COLON} { YDVAR(1, VAR_RATELIMIT_FACTOR) }
  122. +rewrite-domain{COLON} { YDVAR(2, VAR_REWRITE_DOMAIN) }
  123. <INITIAL,val>{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; }
  124.  
  125. /* Quoted strings. Strip leading and ending quotes */
  126. --- unbound-1.5.4.old/util/configparser.y 2015-05-29 16:51:36.000000000 +0200
  127. +++ unbound-1.5.4/util/configparser.y 2015-09-08 16:57:19.412120548 +0200
  128. @@ -122,6 +122,7 @@
  129. %token VAR_RATELIMIT VAR_RATELIMIT_SLABS VAR_RATELIMIT_SIZE
  130. %token VAR_RATELIMIT_FOR_DOMAIN VAR_RATELIMIT_BELOW_DOMAIN VAR_RATELIMIT_FACTOR
  131. %token VAR_CAPS_WHITELIST VAR_CACHE_MAX_NEGATIVE_TTL
  132. +%token VAR_REWRITE_DOMAIN
  133.  
  134. %%
  135. toplevelvars: /* empty */ | toplevelvars toplevelvar ;
  136. @@ -185,7 +186,8 @@
  137. server_ip_transparent | server_ratelimit | server_ratelimit_slabs |
  138. server_ratelimit_size | server_ratelimit_for_domain |
  139. server_ratelimit_below_domain | server_ratelimit_factor |
  140. - server_caps_whitelist | server_cache_max_negative_ttl
  141. + server_caps_whitelist | server_cache_max_negative_ttl |
  142. + server_rewrite_domain
  143. ;
  144. stubstart: VAR_STUB_ZONE
  145. {
  146. @@ -1308,6 +1310,15 @@
  147. free($2);
  148. }
  149. ;
  150. +server_rewrite_domain: VAR_REWRITE_DOMAIN STRING_ARG STRING_ARG
  151. + {
  152. + OUTYY(("P(server_rewrite_domain:%s %s)\n", $2, $3));
  153. + if(!cfg_str2list_insert(&cfg_parser->cfg->
  154. + rewrite_domain, $2, $3))
  155. + fatal_exit("out of memory adding "
  156. + "rewrite-domain");
  157. + }
  158. + ;
  159. stub_name: VAR_NAME STRING_ARG
  160. {
  161. OUTYY(("P(name:%s)\n", $2));
  162. --- unbound-1.5.4.old/util/fptr_wlist.c 2015-04-10 11:59:57.000000000 +0200
  163. +++ unbound-1.5.4/util/fptr_wlist.c 2015-09-07 02:54:02.514863282 +0200
  164. @@ -79,6 +79,8 @@
  165. #include "pythonmod/pythonmod.h"
  166. #endif
  167.  
  168. +#include "rewrite/rewrite.h"
  169. +
  170. int
  171. fptr_whitelist_comm_point(comm_point_callback_t *fptr)
  172. {
  173. @@ -315,6 +317,7 @@
  174. #ifdef WITH_PYTHONMODULE
  175. else if(fptr == &pythonmod_init) return 1;
  176. #endif
  177. + else if(fptr == &rewrite_init) return 1;
  178. return 0;
  179. }
  180.  
  181. @@ -327,6 +330,7 @@
  182. #ifdef WITH_PYTHONMODULE
  183. else if(fptr == &pythonmod_deinit) return 1;
  184. #endif
  185. + else if(fptr == &rewrite_deinit) return 1;
  186. return 0;
  187. }
  188.  
  189. @@ -340,6 +344,7 @@
  190. #ifdef WITH_PYTHONMODULE
  191. else if(fptr == &pythonmod_operate) return 1;
  192. #endif
  193. + else if(fptr == &rewrite_operate) return 1;
  194. return 0;
  195. }
  196.  
  197. @@ -353,6 +358,7 @@
  198. #ifdef WITH_PYTHONMODULE
  199. else if(fptr == &pythonmod_inform_super) return 1;
  200. #endif
  201. + else if(fptr == &rewrite_inform_super) return 1;
  202. return 0;
  203. }
  204.  
  205. @@ -366,6 +372,7 @@
  206. #ifdef WITH_PYTHONMODULE
  207. else if(fptr == &pythonmod_clear) return 1;
  208. #endif
  209. + else if(fptr == &rewrite_clear) return 1;
  210. return 0;
  211. }
  212.  
  213. @@ -378,6 +385,7 @@
  214. #ifdef WITH_PYTHONMODULE
  215. else if(fptr == &pythonmod_get_mem) return 1;
  216. #endif
  217. + else if(fptr == &rewrite_get_mem) return 1;
  218. return 0;
  219. }
  220.  
  221. --- /dev/null 1970-01-01 01:00:00.000000000 +0100
  222. +++ unbound-1.5.4/rewrite/rewrite.c 2015-09-10 14:47:56.866731134 +0200
  223. @@ -0,0 +1,446 @@
  224. +/*
  225. + * Copyright (c) 2015, Manuel Mausz. All rights reserved.
  226. + *
  227. + * This software is open source.
  228. + *
  229. + * Redistribution and use in source and binary forms, with or without
  230. + * modification, are permitted provided that the following conditions
  231. + * are met:
  232. + *
  233. + * Redistributions of source code must retain the above copyright notice,
  234. + * this list of conditions and the following disclaimer.
  235. + *
  236. + * Redistributions in binary form must reproduce the above copyright notice,
  237. + * this list of conditions and the following disclaimer in the documentation
  238. + * and/or other materials provided with the distribution.
  239. + *
  240. + * Neither the name of Viagénie nor the names of its contributors may
  241. + * be used to endorse or promote products derived from this software without
  242. + * specific prior written permission.
  243. + *
  244. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  245. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  246. + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  247. + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
  248. + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  249. + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  250. + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  251. + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  252. + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  253. + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  254. + * POSSIBILITY OF SUCH DAMAGE.
  255. + */
  256. +
  257. +#include "config.h"
  258. +#include "rewrite/rewrite.h"
  259. +#include "sldns/str2wire.h"
  260. +#include "services/cache/dns.h"
  261. +#include "util/config_file.h"
  262. +#include "util/fptr_wlist.h"
  263. +#include "util/regional.h"
  264. +#include "util/data/dname.h"
  265. +
  266. +/**
  267. + * This structure contains module configuration information. One instance of
  268. + * this structure exists per instance of the module. Normally there is only one
  269. + * instance of the module.
  270. + */
  271. +struct rewrite_domain {
  272. + uint8_t* dname;
  273. + size_t dname_len;
  274. + int labs;
  275. +};
  276. +
  277. +struct rewrite_env {
  278. + struct rewrite_domain from;
  279. + struct rewrite_domain to;
  280. + struct rewrite_env *next;
  281. +};
  282. +
  283. +enum rewrite_qstate {
  284. + REWRITE_IS_SUBQUERY = 1,
  285. +};
  286. +
  287. +/**
  288. + * This function applies the configuration found in the parsed configuration
  289. + * file \a cfg to this instance of the rewrite module
  290. + *
  291. + * \param rewrite_env Module-specific global parameters.
  292. + * \param cfg Parsed configuration file.
  293. + */
  294. +static int
  295. +rewrite_apply_cfg(struct rewrite_env** rewrite_env, struct config_file* cfg)
  296. +{
  297. + struct rewrite_env** current = rewrite_env;
  298. + struct config_str2list* p;
  299. + *current = NULL;
  300. + for(p = cfg->rewrite_domain; p; p = p->next) {
  301. + struct rewrite_env* entry =
  302. + (struct rewrite_env*)calloc(1, sizeof(struct rewrite_env));
  303. + if (!(entry->from.dname = sldns_str2wire_dname(p->str, &entry->from.dname_len))) {
  304. + log_err("rewrite-domain: cannot parse source field: %s", p->str);
  305. + return 0;
  306. + }
  307. + entry->from.labs = dname_count_labels(entry->from.dname);
  308. + if (!(entry->to.dname = sldns_str2wire_dname(p->str2, &entry->to.dname_len))) {
  309. + log_err("rewrite-domain: cannot parse target field: %s", p->str2);
  310. + return 0;
  311. + }
  312. + entry->to.labs = dname_count_labels(entry->to.dname);
  313. + if (dname_subdomain_c(entry->to.dname, entry->from.dname)) {
  314. + log_err("rewrite-domain: target %s cannot be a sub-domain of source %s",
  315. + p->str, p->str2);
  316. + return 0;
  317. + }
  318. + *current = entry;
  319. + current = &entry->next;
  320. + verbose(VERB_ALGO, "rewrite: added %s => %s", p->str, p->str2);
  321. + }
  322. + return 1;
  323. +}
  324. +
  325. +/**
  326. + * Initializes this instance of the rewrite module.
  327. + *
  328. + * \param env Global state of all module instances.
  329. + * \param id This instance's ID number.
  330. + */
  331. +int
  332. +rewrite_init(struct module_env* env, int id)
  333. +{
  334. + struct rewrite_env* rewrite_env;
  335. + if (!rewrite_apply_cfg(&rewrite_env, env->cfg)) {
  336. + log_err("rewrite: could not apply configuration settings.");
  337. + return 0;
  338. + }
  339. + env->modinfo[id] = (void*)rewrite_env;
  340. + return 1;
  341. +}
  342. +
  343. +/**
  344. + * Deinitializes this instance of the rewrite module.
  345. + *
  346. + * \param env Global state of all module instances.
  347. + * \param id This instance's ID number.
  348. + */
  349. +void
  350. +rewrite_deinit(struct module_env* env, int id)
  351. +{
  352. + if (!env)
  353. + return;
  354. +
  355. + struct rewrite_env* cur = (struct rewrite_env*)env->modinfo[id];
  356. + struct rewrite_env* next;
  357. + while(cur) {
  358. + next = cur->next;
  359. + free(cur->from.dname);
  360. + free(cur->to.dname);
  361. + free(cur);
  362. + cur = next;
  363. + }
  364. +
  365. + env->modinfo[id] = NULL;
  366. +}
  367. +
  368. +static int
  369. +dname_is_subdomain(uint8_t* dname, size_t dname_len,
  370. + struct rewrite_domain* dom)
  371. +{
  372. + return (dname_len > dom->dname_len
  373. + && dname_strict_subdomain(dname, dname_count_labels(dname),
  374. + dom->dname, dom->labs));
  375. +}
  376. +
  377. +
  378. +static struct rewrite_domain
  379. +rewrite_dname(uint8_t* dname, size_t dname_len, struct rewrite_domain* from,
  380. + struct rewrite_domain* to, struct regional *region)
  381. +{
  382. + struct rewrite_domain new = { NULL, 0 };
  383. + size_t sub_len = dname_len - from->dname_len;
  384. + new.dname_len = sub_len + to->dname_len;
  385. +
  386. + if (!(new.dname = regional_alloc(region, new.dname_len)))
  387. + return new;
  388. + memcpy(new.dname, dname, sub_len);
  389. + memcpy(new.dname + sub_len, to->dname, to->dname_len);
  390. +
  391. + char buf[LDNS_MAX_DOMAINLEN+1];
  392. + dname_str((uint8_t*)new.dname, buf);
  393. + verbose(VERB_ALGO, "rewrite: name rewritten to %s", buf);
  394. +
  395. + return new;
  396. +}
  397. +
  398. +/**
  399. + * Handles the "pass" event for a query. This event is received when a new query
  400. + * is received by this module. The query may have been generated internally by
  401. + * another module, in which case we don't want to do any special processing
  402. + * (this is an interesting discussion topic), or it may be brand new, e.g.
  403. + * received over a socket, in which case we do want to do rewrite processing.
  404. + *
  405. + * \param qstate A structure representing the state of the query that has just
  406. + * received the "pass" event.
  407. + * \param id This module's instance ID.
  408. + *
  409. + * \return The new state of the query.
  410. + */
  411. +static enum module_ext_state
  412. +handle_event_pass(struct module_qstate* qstate, int id)
  413. +{
  414. + if (qstate->minfo[id]) {
  415. + /* we're either inside our sub-query ... */
  416. + if ((uintptr_t)qstate->minfo[id] == REWRITE_IS_SUBQUERY)
  417. + return module_wait_module;
  418. + /* ... or called again after the sub-query has finished */
  419. + else
  420. + return module_finished;
  421. + }
  422. +
  423. + struct rewrite_env* rewrite_env;
  424. + for(rewrite_env = (struct rewrite_env*)qstate->env->modinfo[id];
  425. + rewrite_env; rewrite_env = rewrite_env->next) {
  426. + if (dname_is_subdomain(qstate->qinfo.qname, qstate->qinfo.qname_len,
  427. + &rewrite_env->from)) {
  428. + struct rewrite_domain new = rewrite_dname(
  429. + qstate->qinfo.qname, qstate->qinfo.qname_len,
  430. + &rewrite_env->from, &rewrite_env->to,
  431. + qstate->region);
  432. + if (!new.dname)
  433. + return module_error;
  434. +
  435. + qstate->minfo[id] = (void*)rewrite_env;
  436. +
  437. + /* start our sub query */
  438. + struct module_qstate* subq = NULL;
  439. + struct query_info qinfo = qstate->qinfo;
  440. + qinfo.qname = new.dname;
  441. + qinfo.qname_len = new.dname_len;
  442. + fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
  443. + if (!(*qstate->env->attach_sub)(qstate, &qinfo,
  444. + qstate->query_flags, 0, 0, &subq))
  445. + return module_error;
  446. + if (subq) {
  447. + subq->curmod = id;
  448. + subq->ext_state[id] = module_state_initial;
  449. + subq->minfo[id] = (void*)REWRITE_IS_SUBQUERY;
  450. + }
  451. + return module_wait_subquery;
  452. + }
  453. + }
  454. +
  455. + /* otherwise, pass request to next module. */
  456. + return module_wait_module;
  457. +}
  458. +
  459. +/**
  460. + * This is the module's main() function. It gets called each time a query
  461. + * receives an event which we may need to handle. We respond by updating the
  462. + * state of the query.
  463. + *
  464. + * \param qstate Structure containing the state of the query.
  465. + * \param event Event that has just been received.
  466. + * \param id This module's instance ID.
  467. + * \param outbound State of a DNS query on an authoritative server. We never do
  468. + * our own queries ourselves (other modules do it for us), so
  469. + * this is unused.
  470. + */
  471. +void
  472. +rewrite_operate(struct module_qstate* qstate, enum module_ev event, int id,
  473. + struct outbound_entry* outbound)
  474. +{
  475. + (void)outbound;
  476. + switch(event) {
  477. + case module_event_new:
  478. + case module_event_pass:
  479. + qstate->ext_state[id] = handle_event_pass(qstate, id);
  480. + break;
  481. + case module_event_moddone:
  482. + default:
  483. + qstate->ext_state[id] = module_finished;
  484. + break;
  485. + }
  486. +}
  487. +
  488. +/** allocate (special) rrset keys, return 0 on error */
  489. +static int
  490. +repinfo_alloc_rrset_keys(struct reply_info* rep, struct regional* region)
  491. +{
  492. + size_t i;
  493. + for(i = 0; i < rep->rrset_count; i++) {
  494. + rep->rrsets[i] = (struct ub_packed_rrset_key*)regional_alloc_zero(
  495. + region, sizeof(struct ub_packed_rrset_key));
  496. + if (!rep->rrsets[i])
  497. + return 0;
  498. + rep->rrsets[i]->entry.key = rep->rrsets[i];
  499. + rep->rrsets[i]->entry.data = NULL;
  500. + }
  501. + return 1;
  502. +}
  503. +
  504. +/** copy rrsets from replyinfo to dest replyinfo */
  505. +static int
  506. +repinfo_copy_rrsets(struct reply_info* dest, struct reply_info* from,
  507. + struct regional* region, struct rewrite_env* rewrite_env)
  508. +{
  509. + size_t i, s;
  510. + struct packed_rrset_data* fd, *dd;
  511. + struct ub_packed_rrset_key* fk, *dk;
  512. +
  513. + for(i = 0; i < dest->rrset_count; i++) {
  514. + fk = from->rrsets[i];
  515. + dk = dest->rrsets[i];
  516. + fd = (struct packed_rrset_data*)fk->entry.data;
  517. + dk->rk = fk->rk;
  518. + dk->id = fk->id;
  519. +
  520. + if (dname_is_subdomain(fk->rk.dname, fk->rk.dname_len,
  521. + &rewrite_env->to)) {
  522. + struct rewrite_domain new = rewrite_dname(fk->rk.dname,
  523. + fk->rk.dname_len, &rewrite_env->to,
  524. + &rewrite_env->from, region);
  525. + if (!new.dname)
  526. + return 0;
  527. + dk->rk.dname = new.dname;
  528. + dk->rk.dname_len = new.dname_len;
  529. + dk->entry.hash = rrset_key_hash(&dk->rk);
  530. + }
  531. + else {
  532. + dk->entry.hash = fk->entry.hash;
  533. + dk->rk.dname = (uint8_t*)regional_alloc_init(region,
  534. + fk->rk.dname, fk->rk.dname_len);
  535. + if(!dk->rk.dname)
  536. + return 0;
  537. + }
  538. + s = packed_rrset_sizeof(fd);
  539. + dd = (struct packed_rrset_data*)regional_alloc_init(region,
  540. + fd, s);
  541. + if (!dd)
  542. + return 0;
  543. + packed_rrset_ptr_fixup(dd);
  544. + dk->entry.data = (void*)dd;
  545. + }
  546. +
  547. + return 1;
  548. +}
  549. +
  550. +static int
  551. +rewrite_copy_rrsets(struct module_qstate* from, int id,
  552. + struct module_qstate* dest)
  553. +{
  554. + struct rewrite_env* rewrite_env = (struct rewrite_env*)dest->minfo[id];
  555. +
  556. + /* build the actual reply */
  557. + struct reply_info* frep = from->return_msg->rep;
  558. + struct reply_info* drep = construct_reply_info_base(dest->region,
  559. + frep->flags, frep->qdcount, frep->ttl,
  560. + frep->prefetch_ttl, frep->an_numrrsets,
  561. + frep->ns_numrrsets, frep->ar_numrrsets,
  562. + frep->rrset_count, frep->security);
  563. + if (!drep)
  564. + return 0;
  565. +
  566. + /* allocate ub_key structures special or not */
  567. + if (!repinfo_alloc_rrset_keys(drep, dest->region))
  568. + return 0;
  569. +
  570. + /* copy rrsets from replyinfo to dest and replace dname */
  571. + if (!repinfo_copy_rrsets(drep, frep, dest->region, rewrite_env))
  572. + return 0;
  573. +
  574. + if (!dest->return_msg) {
  575. + dest->return_msg = (struct dns_msg*)regional_alloc(
  576. + dest->region, sizeof(struct dns_msg));
  577. + if (!dest->return_msg)
  578. + return 0;
  579. + dest->return_msg->qinfo = dest->qinfo;
  580. + }
  581. + dest->return_msg->rep = drep;
  582. + return 1;
  583. +}
  584. +
  585. +
  586. +/**
  587. + * This function is called when a sub-query finishes to inform the parent query.
  588. + *
  589. + * We issue two kinds of sub-queries: PTR and A.
  590. + *
  591. + * \param qstate State of the sub-query.
  592. + * \param id This module's instance ID.
  593. + * \param super State of the super-query.
  594. + */
  595. +void
  596. +rewrite_inform_super(struct module_qstate* qstate, int id,
  597. + struct module_qstate* super)
  598. +{
  599. + log_query_info(VERB_ALGO, "rewrite: inform_super, sub is",
  600. + &qstate->qinfo);
  601. + log_query_info(VERB_ALGO, "super is", &super->qinfo);
  602. +
  603. + /* sub-query has finished */
  604. + qstate->minfo[id] = NULL;
  605. +
  606. + /* if there is no successful answer, we're done */
  607. + if (qstate->return_rcode != LDNS_RCODE_NOERROR
  608. + || !qstate->return_msg
  609. + || !qstate->return_msg->rep)
  610. + return;
  611. +
  612. + /* copy and rewrite rrsets */
  613. + if (!rewrite_copy_rrsets(qstate, id, super))
  614. + log_err("rewrite: cannot copy rrsets from subquery");
  615. +
  616. + /* store the generated response in cache */
  617. + if (!dns_cache_store(super->env, &super->qinfo, super->return_msg->rep,
  618. + 0, 0, 0, NULL, super->query_flags))
  619. + log_err("out of memory");
  620. +
  621. +}
  622. +
  623. +/**
  624. + * Clear module-specific data from query state. Since we do not allocate memory,
  625. + * it's just a matter of setting a pointer to NULL.
  626. + *
  627. + * \param qstate Query state.
  628. + * \param id This module's instance ID.
  629. + */
  630. +void
  631. +rewrite_clear(struct module_qstate* qstate, int id)
  632. +{
  633. + qstate->minfo[id] = NULL;
  634. +}
  635. +
  636. +/**
  637. + * Returns the amount of global memory that this module uses, not including
  638. + * per-query data.
  639. + *
  640. + * \param env Module environment.
  641. + * \param id This module's instance ID.
  642. + */
  643. +size_t
  644. +rewrite_get_mem(struct module_env* env, int id)
  645. +{
  646. + size_t mem = 0;
  647. + struct rewrite_env* cur;
  648. + for(cur = (struct rewrite_env*)env->modinfo[id]; cur; cur = cur->next) {
  649. + mem += sizeof(*cur);
  650. + mem += cur->from.dname_len * sizeof(*cur->from.dname);
  651. + mem += cur->to.dname_len * sizeof(*cur->to.dname);
  652. + }
  653. + return mem;
  654. +}
  655. +
  656. +/**
  657. + * The rewrite function block.
  658. + */
  659. +static struct module_func_block rewrite_block = {
  660. + "rewrite",
  661. + &rewrite_init, &rewrite_deinit, &rewrite_operate, &rewrite_inform_super,
  662. + &rewrite_clear, &rewrite_get_mem
  663. +};
  664. +
  665. +struct module_func_block *
  666. +rewrite_get_funcblock()
  667. +{
  668. + return &rewrite_block;
  669. +}
  670. --- /dev/null 1970-01-01 01:00:00.000000000 +0100
  671. +++ unbound-1.5.4/rewrite/rewrite.h 2015-09-08 00:36:02.520835089 +0200
  672. @@ -0,0 +1,63 @@
  673. +/*
  674. + * Copyright (c) 2015, Manuel Mausz. All rights reserved.
  675. + *
  676. + * This software is open source.
  677. + *
  678. + * Redistribution and use in source and binary forms, with or without
  679. + * modification, are permitted provided that the following conditions
  680. + * are met:
  681. + *
  682. + * Redistributions of source code must retain the above copyright notice,
  683. + * this list of conditions and the following disclaimer.
  684. + *
  685. + * Redistributions in binary form must reproduce the above copyright notice,
  686. + * this list of conditions and the following disclaimer in the documentation
  687. + * and/or other materials provided with the distribution.
  688. + *
  689. + * Neither the name of the NLNET LABS nor the names of its contributors may
  690. + * be used to endorse or promote products derived from this software without
  691. + * specific prior written permission.
  692. + *
  693. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  694. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  695. + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  696. + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
  697. + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  698. + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  699. + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  700. + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  701. + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  702. + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  703. + * POSSIBILITY OF SUCH DAMAGE.
  704. + */
  705. +
  706. +#ifndef REWRITE_REWRITE_H
  707. +#define REWRITE_REWRITE_H
  708. +#include "util/module.h"
  709. +
  710. +/**
  711. + * Get the rewrite function block.
  712. + * @return: function block with function pointers to rewrite methods.
  713. + */
  714. +struct module_func_block *rewrite_get_funcblock(void);
  715. +
  716. +/** rewrite init */
  717. +int rewrite_init(struct module_env* env, int id);
  718. +
  719. +/** rewrite deinit */
  720. +void rewrite_deinit(struct module_env* env, int id);
  721. +
  722. +/** rewrite operate on a query */
  723. +void rewrite_operate(struct module_qstate* qstate, enum module_ev event, int id,
  724. + struct outbound_entry* outbound);
  725. +
  726. +void rewrite_inform_super(struct module_qstate* qstate, int id,
  727. + struct module_qstate* super);
  728. +
  729. +/** rewrite cleanup query state */
  730. +void rewrite_clear(struct module_qstate* qstate, int id);
  731. +
  732. +/** rewrite alloc size routine */
  733. +size_t rewrite_get_mem(struct module_env* env, int id);
  734. +
  735. +#endif
  736.