aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gns/Makefile.am14
-rw-r--r--src/gns/gnunet-service-gns_resolver.c221
-rw-r--r--src/gns/test_gns_simple_srv_lookup.c387
-rw-r--r--src/include/gnunet_dnsparser_lib.h3
-rw-r--r--src/include/gnunet_gns_service.h1
5 files changed, 545 insertions, 81 deletions
diff --git a/src/gns/Makefile.am b/src/gns/Makefile.am
index bb10a5973..c65d52492 100644
--- a/src/gns/Makefile.am
+++ b/src/gns/Makefile.am
@@ -45,6 +45,7 @@ check_PROGRAMS = \
45 test_gns_simple_lookup \ 45 test_gns_simple_lookup \
46 test_gns_simple_delegated_lookup \ 46 test_gns_simple_delegated_lookup \
47 test_gns_simple_mx_lookup \ 47 test_gns_simple_mx_lookup \
48 test_gns_simple_srv_lookup \
48 test_gns_simple_zkey_lookup \ 49 test_gns_simple_zkey_lookup \
49 test_gns_dht_delegated_lookup \ 50 test_gns_dht_delegated_lookup \
50 test_gns_pseu_shorten \ 51 test_gns_pseu_shorten \
@@ -115,6 +116,19 @@ test_gns_simple_mx_lookup_DEPENDENCIES = \
115 $(top_builddir)/src/gns/libgnunetgns.la \ 116 $(top_builddir)/src/gns/libgnunetgns.la \
116 $(top_builddir)/src/testing_old/libgnunettesting_old.la 117 $(top_builddir)/src/testing_old/libgnunettesting_old.la
117 118
119test_gns_simple_srv_lookup_SOURCES = \
120 test_gns_simple_srv_lookup.c
121test_gns_simple_srv_lookup_LDADD = \
122 $(top_builddir)/src/util/libgnunetutil.la \
123 $(top_builddir)/src/namestore/libgnunetnamestore.la \
124 $(top_builddir)/src/gns/libgnunetgns.la \
125 $(top_builddir)/src/testing_old/libgnunettesting_old.la
126test_gns_simple_srv_lookup_DEPENDENCIES = \
127 $(top_builddir)/src/util/libgnunetutil.la \
128 $(top_builddir)/src/namestore/libgnunetnamestore.la \
129 $(top_builddir)/src/gns/libgnunetgns.la \
130 $(top_builddir)/src/testing_old/libgnunettesting_old.la
131
118test_gns_simple_zkey_lookup_SOURCES = \ 132test_gns_simple_zkey_lookup_SOURCES = \
119 test_gns_simple_zkey_lookup.c 133 test_gns_simple_zkey_lookup.c
120test_gns_simple_zkey_lookup_LDADD = \ 134test_gns_simple_zkey_lookup_LDADD = \
diff --git a/src/gns/gnunet-service-gns_resolver.c b/src/gns/gnunet-service-gns_resolver.c
index 045112eae..bbeea86f4 100644
--- a/src/gns/gnunet-service-gns_resolver.c
+++ b/src/gns/gnunet-service-gns_resolver.c
@@ -97,6 +97,31 @@ static struct GetPseuAuthorityHandle *gph_tail;
97 */ 97 */
98static unsigned long long rid = 0; 98static unsigned long long rid = 0;
99 99
100static int
101is_srv (char* name)
102{
103 char* ndup;
104 int ret = 1;
105
106 if (*name != '_')
107 return 0;
108 if (NULL == strstr (name, "._"))
109 return 0;
110
111 ndup = GNUNET_strdup (name);
112 strtok (ndup, ".");
113
114 if (NULL == strtok (NULL, "."))
115 ret = 0;
116
117 if (NULL == strtok (NULL, "."))
118 ret = 0;
119
120 if (NULL != strtok (NULL, "."))
121 ret = 0;
122
123 return ret;
124}
100 125
101/** 126/**
102 * Determine if this name is canonical. 127 * Determine if this name is canonical.
@@ -110,14 +135,23 @@ static unsigned long long rid = 0;
110static int 135static int
111is_canonical(char* name) 136is_canonical(char* name)
112{ 137{
113 uint32_t len = strlen(name); 138 char* ndup;
114 int i; 139 char* tok;
140
141 ndup = GNUNET_strdup (name);
142 tok = strtok (ndup, ".");
115 143
116 for (i=0; i<len; i++) 144 for (tok = strtok (NULL, "."); tok != NULL; tok = strtok (NULL, "."))
117 { 145 {
118 if (*(name+i) == '.') 146 /*
119 return 0; 147 * probably srv
148 */
149 if (*tok == '_')
150 continue;
151 GNUNET_free (ndup);
152 return 0;
120 } 153 }
154 GNUNET_free (ndup);
121 return 1; 155 return 1;
122} 156}
123 157
@@ -1126,12 +1160,12 @@ resolve_record_dht (struct ResolverHandle *rh)
1126 * @param signature the signature of the authority for the record data 1160 * @param signature the signature of the authority for the record data
1127 */ 1161 */
1128static void 1162static void
1129process_record_result_ns(void* cls, 1163process_record_result_ns (void* cls,
1130 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *key, 1164 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *key,
1131 struct GNUNET_TIME_Absolute expiration, 1165 struct GNUNET_TIME_Absolute expiration,
1132 const char *name, unsigned int rd_count, 1166 const char *name, unsigned int rd_count,
1133 const struct GNUNET_NAMESTORE_RecordData *rd, 1167 const struct GNUNET_NAMESTORE_RecordData *rd,
1134 const struct GNUNET_CRYPTO_RsaSignature *signature) 1168 const struct GNUNET_CRYPTO_RsaSignature *signature)
1135{ 1169{
1136 struct ResolverHandle *rh; 1170 struct ResolverHandle *rh;
1137 struct RecordLookupHandle *rlh; 1171 struct RecordLookupHandle *rlh;
@@ -2313,6 +2347,7 @@ process_delegation_result_dht(void* cls,
2313#define MAX_SOA_LENGTH sizeof(uint32_t)+sizeof(uint32_t)+sizeof(uint32_t)+sizeof(uint32_t)\ 2347#define MAX_SOA_LENGTH sizeof(uint32_t)+sizeof(uint32_t)+sizeof(uint32_t)+sizeof(uint32_t)\
2314 +(MAX_DNS_NAME_LENGTH*2) 2348 +(MAX_DNS_NAME_LENGTH*2)
2315#define MAX_MX_LENGTH sizeof(uint16_t)+MAX_DNS_NAME_LENGTH 2349#define MAX_MX_LENGTH sizeof(uint16_t)+MAX_DNS_NAME_LENGTH
2350#define MAX_SRV_LENGTH (sizeof(uint16_t)*3)+MAX_DNS_NAME_LENGTH
2316 2351
2317 2352
2318static void 2353static void
@@ -2365,6 +2400,7 @@ finish_lookup(struct ResolverHandle *rh,
2365 char new_rr_data[MAX_DNS_NAME_LENGTH]; 2400 char new_rr_data[MAX_DNS_NAME_LENGTH];
2366 char new_mx_data[MAX_MX_LENGTH]; 2401 char new_mx_data[MAX_MX_LENGTH];
2367 char new_soa_data[MAX_SOA_LENGTH]; 2402 char new_soa_data[MAX_SOA_LENGTH];
2403 char new_srv_data[MAX_SRV_LENGTH];
2368 struct GNUNET_NAMESTORE_RecordData p_rd[rd_count]; 2404 struct GNUNET_NAMESTORE_RecordData p_rd[rd_count];
2369 char* repl_string; 2405 char* repl_string;
2370 char* pos; 2406 char* pos;
@@ -2385,7 +2421,8 @@ finish_lookup(struct ResolverHandle *rh,
2385 if (rd[i].record_type != GNUNET_GNS_RECORD_TYPE_NS && 2421 if (rd[i].record_type != GNUNET_GNS_RECORD_TYPE_NS &&
2386 rd[i].record_type != GNUNET_GNS_RECORD_TYPE_CNAME && 2422 rd[i].record_type != GNUNET_GNS_RECORD_TYPE_CNAME &&
2387 rd[i].record_type != GNUNET_GNS_RECORD_MX && 2423 rd[i].record_type != GNUNET_GNS_RECORD_MX &&
2388 rd[i].record_type != GNUNET_GNS_RECORD_TYPE_SOA) 2424 rd[i].record_type != GNUNET_GNS_RECORD_TYPE_SOA &&
2425 rd[i].record_type != GNUNET_GNS_RECORD_TYPE_SRV)
2389 { 2426 {
2390 p_rd[i].data = rd[i].data; 2427 p_rd[i].data = rd[i].data;
2391 continue; 2428 continue;
@@ -2408,7 +2445,7 @@ finish_lookup(struct ResolverHandle *rh,
2408 offset = 0; 2445 offset = 0;
2409 if (rd[i].record_type == GNUNET_GNS_RECORD_MX) 2446 if (rd[i].record_type == GNUNET_GNS_RECORD_MX)
2410 { 2447 {
2411 memcpy(new_mx_data, (char*)rd[i].data, sizeof(uint16_t)); 2448 memcpy (new_mx_data, (char*)rd[i].data, sizeof(uint16_t));
2412 offset = sizeof(uint16_t); 2449 offset = sizeof(uint16_t);
2413 pos = new_mx_data+offset; 2450 pos = new_mx_data+offset;
2414 expand_plus(&pos, (char*)rd[i].data+sizeof(uint16_t), 2451 expand_plus(&pos, (char*)rd[i].data+sizeof(uint16_t),
@@ -2417,6 +2454,20 @@ finish_lookup(struct ResolverHandle *rh,
2417 p_rd[i].data = new_mx_data; 2454 p_rd[i].data = new_mx_data;
2418 p_rd[i].data_size = offset; 2455 p_rd[i].data_size = offset;
2419 } 2456 }
2457 else if (rd[i].record_type == GNUNET_GNS_RECORD_TYPE_SRV)
2458 {
2459 /*
2460 * Prio, weight and port
2461 */
2462 memcpy (new_srv_data, (char*)rd[i].data, sizeof (uint16_t) * 3);
2463 offset = sizeof (uint16_t) * 3;
2464 pos = new_srv_data+offset;
2465 expand_plus(&pos, (char*)rd[i].data+(sizeof(uint16_t)*3),
2466 repl_string);
2467 offset += strlen(new_srv_data+(sizeof(uint16_t)*3))+1;
2468 p_rd[i].data = new_srv_data;
2469 p_rd[i].data_size = offset;
2470 }
2420 else if (rd[i].record_type == GNUNET_GNS_RECORD_TYPE_SOA) 2471 else if (rd[i].record_type == GNUNET_GNS_RECORD_TYPE_SOA)
2421 { 2472 {
2422 /* expand mname and rname */ 2473 /* expand mname and rname */
@@ -2501,6 +2552,8 @@ handle_record_ns (void* cls, struct ResolverHandle *rh,
2501{ 2552{
2502 struct RecordLookupHandle* rlh; 2553 struct RecordLookupHandle* rlh;
2503 rlh = (struct RecordLookupHandle*) cls; 2554 rlh = (struct RecordLookupHandle*) cls;
2555 int check_dht = GNUNET_YES;
2556
2504 if (rd_count == 0) 2557 if (rd_count == 0)
2505 { 2558 {
2506 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 2559 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
@@ -2519,12 +2572,22 @@ handle_record_ns (void* cls, struct ResolverHandle *rh,
2519 * would already have an entry in the NS for the record) 2572 * would already have an entry in the NS for the record)
2520 * 5. We are not in cache only mode 2573 * 5. We are not in cache only mode
2521 */ 2574 */
2522 if (( ((rh->status & RSL_RECORD_EXPIRED) != 0) || 2575 if (((rh->status & RSL_RECORD_EXPIRED) != 0) &&
2523 ((rh->status & RSL_RECORD_EXISTS) == 0) ) && 2576 ((rh->status & RSL_RECORD_EXISTS) == 0) )
2524 GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone, 2577 check_dht = GNUNET_NO;
2525 &rh->private_local_zone) && 2578
2526 (strcmp(rh->name, "+") == 0) && 2579 if (0 != GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone,
2527 (rh->only_cached == GNUNET_NO)) 2580 &rh->private_local_zone))
2581 check_dht = GNUNET_NO;
2582
2583 if ((strcmp (rh->name, "+") != 0) && (is_srv (rh->name) != 0))
2584 check_dht = GNUNET_NO;
2585
2586
2587 if (rh->only_cached == GNUNET_YES)
2588 check_dht = GNUNET_NO;
2589
2590 if (GNUNET_YES == check_dht)
2528 { 2591 {
2529 rh->proc = &handle_record_dht; 2592 rh->proc = &handle_record_dht;
2530 resolve_record_dht(rh); 2593 resolve_record_dht(rh);
@@ -2559,7 +2622,7 @@ pop_tld(char* name, char* dest)
2559{ 2622{
2560 uint32_t len; 2623 uint32_t len;
2561 2624
2562 if (is_canonical(name)) 2625 if (is_canonical (name))
2563 { 2626 {
2564 strcpy(dest, name); 2627 strcpy(dest, name);
2565 strcpy(name, ""); 2628 strcpy(name, "");
@@ -2757,6 +2820,7 @@ handle_delegation_ns (void* cls, struct ResolverHandle *rh,
2757{ 2820{
2758 struct RecordLookupHandle* rlh; 2821 struct RecordLookupHandle* rlh;
2759 rlh = (struct RecordLookupHandle*) cls; 2822 rlh = (struct RecordLookupHandle*) cls;
2823 int check_dht = GNUNET_YES;
2760 int s_len = 0; 2824 int s_len = 0;
2761 2825
2762 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 2826 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
@@ -2920,9 +2984,19 @@ handle_delegation_ns (void* cls, struct ResolverHandle *rh,
2920 * and exists 2984 * and exists
2921 * or we are authority 2985 * or we are authority
2922 **/ 2986 **/
2923 if (((rh->status & RSL_RECORD_EXISTS) && (!(rh->status & RSL_RECORD_EXPIRED))) 2987
2924 || !GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone, 2988 if ((rh->status & RSL_RECORD_EXISTS) &&
2925 &rh->private_local_zone)) 2989 !(rh->status & RSL_RECORD_EXPIRED))
2990 check_dht = GNUNET_NO;
2991
2992 if (0 == GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone,
2993 &rh->private_local_zone))
2994 check_dht = GNUNET_NO;
2995
2996 if (rh->only_cached == GNUNET_YES)
2997 check_dht = GNUNET_NO;
2998
2999 if (check_dht == GNUNET_NO)
2926 { 3000 {
2927 if (is_canonical(rh->name)) 3001 if (is_canonical(rh->name))
2928 { 3002 {
@@ -2946,15 +3020,6 @@ handle_delegation_ns (void* cls, struct ResolverHandle *rh,
2946 return; 3020 return;
2947 } 3021 }
2948 3022
2949 if (rh->only_cached == GNUNET_YES)
2950 {
2951 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2952 "GNS_PHASE_DELEGATE_NS-%llu: Only cache resolution, no result\n",
2953 rh->id, rh->name);
2954 finish_lookup(rh, rlh, rd_count, rd);
2955 return;
2956 }
2957
2958 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 3023 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2959 "GNS_PHASE_DELEGATE_NS-%llu: Trying to resolve delegation for %s via DHT\n", 3024 "GNS_PHASE_DELEGATE_NS-%llu: Trying to resolve delegation for %s via DHT\n",
2960 rh->id, rh->name); 3025 rh->id, rh->name);
@@ -2994,29 +3059,29 @@ process_delegation_result_ns (void* cls,
2994 struct GNUNET_TIME_Absolute et; 3059 struct GNUNET_TIME_Absolute et;
2995 3060
2996 rh = (struct ResolverHandle *)cls; 3061 rh = (struct ResolverHandle *)cls;
2997 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 3062 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2998 "GNS_PHASE_DELEGATE_NS-%llu: Got %d records from authority lookup\n", 3063 "GNS_PHASE_DELEGATE_NS-%llu: Got %d records from authority lookup\n",
2999 rh->id, rd_count); 3064 rh->id, rd_count);
3000 3065
3001 GNUNET_CRYPTO_short_hash(key, 3066 GNUNET_CRYPTO_short_hash (key,
3002 sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), 3067 sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
3003 &zone); 3068 &zone);
3004 remaining_time = GNUNET_TIME_absolute_get_remaining (expiration); 3069 remaining_time = GNUNET_TIME_absolute_get_remaining (expiration);
3005 3070
3006 rh->status = 0; 3071 rh->status = 0;
3007 3072
3008 if (name != NULL) 3073 if (name != NULL)
3009 { 3074 {
3010 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 3075 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3011 "GNS_PHASE_DELEGATE_NS-%llu: Records with name %s exist.\n", 3076 "GNS_PHASE_DELEGATE_NS-%llu: Records with name %s exist.\n",
3012 rh->id, name); 3077 rh->id, name);
3013 rh->status |= RSL_RECORD_EXISTS; 3078 rh->status |= RSL_RECORD_EXISTS;
3014 3079
3015 if (remaining_time.rel_value == 0) 3080 if (remaining_time.rel_value == 0)
3016 { 3081 {
3017 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 3082 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3018 "GNS_PHASE_DELEGATE_NS-%llu: Record set %s expired.\n", 3083 "GNS_PHASE_DELEGATE_NS-%llu: Record set %s expired.\n",
3019 rh->id, name); 3084 rh->id, name);
3020 rh->status |= RSL_RECORD_EXPIRED; 3085 rh->status |= RSL_RECORD_EXPIRED;
3021 } 3086 }
3022 } 3087 }
@@ -3035,31 +3100,29 @@ process_delegation_result_ns (void* cls,
3035 * Promote this authority back to a name maybe it is 3100 * Promote this authority back to a name maybe it is
3036 * our record. 3101 * our record.
3037 */ 3102 */
3038 if (strcmp(rh->name, "") == 0) 3103 if (strcmp (rh->name, "") == 0)
3039 { 3104 {
3040 /* simply promote back */ 3105 /* simply promote back */
3041 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 3106 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3042 "GNS_PHASE_DELEGATE_NS-%llu: Promoting %s back to name\n", 3107 "GNS_PHASE_DELEGATE_NS-%llu: Promoting %s back to name\n",
3043 rh->id, rh->authority_name); 3108 rh->id, rh->authority_name);
3044 strcpy(rh->name, rh->authority_name); 3109 strcpy (rh->name, rh->authority_name);
3045 } 3110 }
3046 else 3111 else
3047 { 3112 {
3048 /* add back to existing name */ 3113 /* add back to existing name */
3049 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 3114 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3050 "GNS_PHASE_DELEGATE_NS-%llu: Adding %s back to %s\n", 3115 "GNS_PHASE_DELEGATE_NS-%llu: Adding %s back to %s\n",
3051 rh->id, rh->authority_name, rh->name); 3116 rh->id, rh->authority_name, rh->name);
3052 //memset(new_name, 0, strlen(rh->name) + strlen(rh->authority_name) + 2); 3117 GNUNET_snprintf (new_name, MAX_DNS_NAME_LENGTH, "%s.%s",
3053 GNUNET_snprintf(new_name, MAX_DNS_NAME_LENGTH, "%s.%s", 3118 rh->name, rh->authority_name);
3054 rh->name, rh->authority_name); 3119 strcpy (rh->name, new_name);
3055 //strcpy(new_name, rh->name); 3120 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3056 //strcpy(new_name+strlen(new_name), "."); 3121 "GNS_PHASE_DELEGATE_NS-%llu: %s restored\n",
3057 //strcpy(new_name+strlen(new_name), rh->authority_name); 3122 rh->id, rh->name);
3058 strcpy(rh->name, new_name);
3059 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
3060 "GNS_PHASE_DELEGATE_NS-%llu: %s restored\n", rh->id, rh->name);
3061 } 3123 }
3062 rh->proc(rh->proc_cls, rh, 0, NULL); 3124
3125 rh->proc (rh->proc_cls, rh, 0, NULL);
3063 return; 3126 return;
3064 } 3127 }
3065 3128
@@ -3068,7 +3131,7 @@ process_delegation_result_ns (void* cls,
3068 * move on with query 3131 * move on with query
3069 * Note only 1 pkey should have been returned.. anything else would be strange 3132 * Note only 1 pkey should have been returned.. anything else would be strange
3070 */ 3133 */
3071 for (i=0; i<rd_count;i++) 3134 for (i=0; i < rd_count;i++)
3072 { 3135 {
3073 3136
3074 /** 3137 /**
@@ -3118,11 +3181,11 @@ process_delegation_result_ns (void* cls,
3118 3181
3119 rh->status |= RSL_DELEGATE_PKEY; 3182 rh->status |= RSL_DELEGATE_PKEY;
3120 3183
3121 if (ignore_pending_records && 3184 if ((ignore_pending_records != 0) &&
3122 (rd[i].flags & GNUNET_NAMESTORE_RF_PENDING)) 3185 (rd[i].flags & GNUNET_NAMESTORE_RF_PENDING))
3123 { 3186 {
3124 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 3187 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3125 "GNS_PHASE_DELEGATE_NS-%llu: PKEY for %s is pending user confirmation.\n", 3188 "GNS_PHASE_DELEGATE_NS-%llu: PKEY for %s is pending user confirmation.\n",
3126 rh->id, 3189 rh->id,
3127 name); 3190 name);
3128 continue; 3191 continue;
@@ -3133,16 +3196,16 @@ process_delegation_result_ns (void* cls,
3133 if ((GNUNET_TIME_absolute_get_remaining (et)).rel_value 3196 if ((GNUNET_TIME_absolute_get_remaining (et)).rel_value
3134 == 0) 3197 == 0)
3135 { 3198 {
3136 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 3199 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3137 "GNS_PHASE_DELEGATE_NS-%llu: This pkey is expired.\n", 3200 "GNS_PHASE_DELEGATE_NS-%llu: This pkey is expired.\n",
3138 rh->id); 3201 rh->id);
3139 if (remaining_time.rel_value == 0) 3202 if (remaining_time.rel_value == 0)
3140 { 3203 {
3141 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 3204 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3142 "GNS_PHASE_DELEGATE_NS-%llu: This dht entry is expired.\n", 3205 "GNS_PHASE_DELEGATE_NS-%llu: This dht entry is expired.\n",
3143 rh->id); 3206 rh->id);
3144 rh->authority_chain_head->fresh = 0; 3207 rh->authority_chain_head->fresh = 0;
3145 rh->proc(rh->proc_cls, rh, 0, NULL); 3208 rh->proc (rh->proc_cls, rh, 0, NULL);
3146 return; 3209 return;
3147 } 3210 }
3148 3211
@@ -3152,13 +3215,13 @@ process_delegation_result_ns (void* cls,
3152 /** 3215 /**
3153 * Resolve rest of query with new authority 3216 * Resolve rest of query with new authority
3154 */ 3217 */
3155 GNUNET_assert(rd[i].record_type == GNUNET_GNS_RECORD_PKEY); 3218 GNUNET_assert (rd[i].record_type == GNUNET_GNS_RECORD_PKEY);
3156 memcpy(&rh->authority, rd[i].data, 3219 memcpy (&rh->authority, rd[i].data,
3157 sizeof(struct GNUNET_CRYPTO_ShortHashCode)); 3220 sizeof (struct GNUNET_CRYPTO_ShortHashCode));
3158 struct AuthorityChain *auth = GNUNET_malloc(sizeof(struct AuthorityChain)); 3221 struct AuthorityChain *auth = GNUNET_malloc(sizeof (struct AuthorityChain));
3159 auth->zone = rh->authority; 3222 auth->zone = rh->authority;
3160 memset(auth->name, 0, strlen(rh->authority_name)+1); 3223 memset (auth->name, 0, strlen (rh->authority_name)+1);
3161 strcpy(auth->name, rh->authority_name); 3224 strcpy (auth->name, rh->authority_name);
3162 GNUNET_CONTAINER_DLL_insert (rh->authority_chain_head, 3225 GNUNET_CONTAINER_DLL_insert (rh->authority_chain_head,
3163 rh->authority_chain_tail, 3226 rh->authority_chain_tail,
3164 auth); 3227 auth);
diff --git a/src/gns/test_gns_simple_srv_lookup.c b/src/gns/test_gns_simple_srv_lookup.c
new file mode 100644
index 000000000..b23d6ded3
--- /dev/null
+++ b/src/gns/test_gns_simple_srv_lookup.c
@@ -0,0 +1,387 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20/**
21 * @file gns/test_gns_simple_srv_lookup.c
22 * @brief base testcase for testing GNS SRV lookups
23 *
24 */
25#include "platform.h"
26#include "gnunet_testing_lib.h"
27#include "gnunet_core_service.h"
28#include "block_dns.h"
29#include "gnunet_signatures.h"
30#include "gnunet_namestore_service.h"
31#include "../namestore/namestore.h"
32#include "gnunet_dnsparser_lib.h"
33#include "gnunet_gns_service.h"
34
35/* DEFINES */
36#define VERBOSE GNUNET_YES
37
38/* Timeout for entire testcase */
39#define TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 20)
40
41/* If number of peers not in config file, use this number */
42#define DEFAULT_NUM_PEERS 2
43
44/* test records to resolve */
45#define TEST_DOMAIN "_sip._tcp.bob.gnunet"
46#define TEST_IP "127.0.0.1"
47#define TEST_RECORD_NAME "sipserver"
48#define TEST_RECORD_NAME_SRV "_sip._tcp"
49#define TEST_SRV_NAME "sipserver.+"
50#define TEST_EXPECTED_SRV "sipserver.bob.gnunet"
51
52#define TEST_AUTHORITY_NAME "bob"
53
54#define KEYFILE_BOB "../namestore/zonefiles/HGU0A0VCU334DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey"
55
56/* Globals */
57
58/**
59 * Directory to store temp data in, defined in config file
60 */
61static char *test_directory;
62
63static struct GNUNET_TESTING_PeerGroup *pg;
64
65/* Task handle to use to schedule test failure */
66GNUNET_SCHEDULER_TaskIdentifier die_task;
67
68/* Global return value (0 for success, anything else for failure) */
69static int ok;
70
71static struct GNUNET_NAMESTORE_Handle *namestore_handle;
72
73static struct GNUNET_GNS_Handle *gns_handle;
74
75const struct GNUNET_CONFIGURATION_Handle *cfg;
76
77/**
78 * Check whether peers successfully shut down.
79 */
80void
81shutdown_callback (void *cls, const char *emsg)
82{
83 if (emsg != NULL)
84 {
85 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error on shutdown! ret=%d\n", ok);
86 if (ok == 0)
87 ok = 2;
88 }
89
90 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "done(ret=%d)!\n", ok);
91}
92
93static void
94on_lookup_result(void *cls, uint32_t rd_count,
95 const struct GNUNET_NAMESTORE_RecordData *rd)
96{
97 int i;
98 uint16_t *srv_data;
99 char* srv;
100
101 if (rd_count == 0)
102 {
103 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
104 "Lookup failed, rp_filtering?\n");
105 ok = 2;
106 }
107 else
108 {
109 ok = 1;
110 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "name: %s\n", (char*)cls);
111 for (i=0; i<rd_count; i++)
112 {
113 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "type: %d\n", rd[i].record_type);
114 if (rd[i].record_type == GNUNET_GNS_RECORD_TYPE_SRV)
115 {
116 srv_data = (uint16_t*)rd[i].data;
117 srv = (char*)&srv_data[3];
118 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
119 "Got SRV %s with p=%d,w=%d,port=%d\n",
120 srv, srv_data, &srv_data[1], &srv_data[2]);
121 if (0 == strcmp(srv, TEST_EXPECTED_SRV))
122 {
123 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
124 "%s correctly resolved to %s!\n", TEST_DOMAIN,
125 TEST_EXPECTED_SRV);
126 ok = 0;
127 }
128 }
129 }
130 }
131
132 GNUNET_GNS_disconnect(gns_handle);
133 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Shutting down peer1!\n");
134 GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL);
135}
136
137
138/**
139 * Function scheduled to be run on the successful start of services
140 * tries to look up the dns record for TEST_DOMAIN
141 */
142static void
143commence_testing (void *cls, int32_t success, const char *emsg)
144{
145 GNUNET_NAMESTORE_disconnect(namestore_handle, GNUNET_YES);
146
147 gns_handle = GNUNET_GNS_connect(cfg);
148
149 if (NULL == gns_handle)
150 {
151 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
152 "Failed to connect to GNS!\n");
153 }
154
155 GNUNET_GNS_lookup(gns_handle, TEST_DOMAIN, GNUNET_GNS_RECORD_TYPE_SRV,
156 GNUNET_NO,
157 NULL,
158 &on_lookup_result, TEST_DOMAIN);
159}
160
161/**
162 * Continuation for the GNUNET_DHT_get_stop call, so that we don't shut
163 * down the peers without freeing memory associated with GET request.
164 */
165static void
166end_badly_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
167{
168
169 if (pg != NULL)
170 GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL);
171 GNUNET_SCHEDULER_cancel (die_task);
172}
173
174/**
175 * Check if the get_handle is being used, if so stop the request. Either
176 * way, schedule the end_badly_cont function which actually shuts down the
177 * test.
178 */
179static void
180end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
181{
182 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failing test with error: `%s'!\n",
183 (char *) cls);
184 GNUNET_SCHEDULER_add_now (&end_badly_cont, NULL);
185 ok = 1;
186}
187
188GNUNET_NETWORK_STRUCT_BEGIN
189struct srv_data
190{
191 uint16_t prio GNUNET_PACKED;
192 uint16_t weight GNUNET_PACKED;
193 uint16_t port GNUNET_PACKED;
194};
195GNUNET_NETWORK_STRUCT_END
196
197static void
198do_lookup(void *cls, const struct GNUNET_PeerIdentity *id,
199 const struct GNUNET_CONFIGURATION_Handle *_cfg,
200 struct GNUNET_TESTING_Daemon *d, const char *emsg)
201{
202 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded alice_pkey;
203 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded bob_pkey;
204 struct GNUNET_CRYPTO_RsaPrivateKey *alice_key;
205 struct GNUNET_CRYPTO_RsaPrivateKey *bob_key;
206 struct GNUNET_CRYPTO_ShortHashCode bob_hash;
207 struct GNUNET_CRYPTO_RsaSignature *sig;
208 char* alice_keyfile;
209 struct srv_data *srv_data;
210 struct GNUNET_TIME_Absolute et;
211
212 cfg = _cfg;
213
214 GNUNET_SCHEDULER_cancel (die_task);
215
216 /* put records into namestore */
217 namestore_handle = GNUNET_NAMESTORE_connect(cfg);
218 if (NULL == namestore_handle)
219 {
220 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to connect to namestore\n");
221 ok = -1;
222 return;
223 }
224
225 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns",
226 "ZONEKEY",
227 &alice_keyfile))
228 {
229 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to get key from cfg\n");
230 ok = -1;
231 return;
232 }
233
234 alice_key = GNUNET_CRYPTO_rsa_key_create_from_file (alice_keyfile);
235 bob_key = GNUNET_CRYPTO_rsa_key_create_from_file (KEYFILE_BOB);
236
237 GNUNET_CRYPTO_rsa_key_get_public (alice_key, &alice_pkey);
238 GNUNET_CRYPTO_rsa_key_get_public (bob_key, &bob_pkey);
239
240 struct GNUNET_NAMESTORE_RecordData rd;
241 char* ip = TEST_IP;
242 struct in_addr *sipserver = GNUNET_malloc (sizeof (struct in_addr));
243 srv_data = GNUNET_malloc (sizeof (struct srv_data) + strlen (TEST_SRV_NAME) + 1);
244 uint16_t srv_weight = 60;
245 uint16_t srv_prio = 50;
246 uint16_t srv_port = 5060;
247
248 rd.expiration_time = UINT64_MAX;
249 GNUNET_assert(1 == inet_pton (AF_INET, ip, sipserver));
250
251 GNUNET_CRYPTO_short_hash(&bob_pkey, sizeof(bob_pkey), &bob_hash);
252
253 rd.data_size = sizeof(struct GNUNET_CRYPTO_ShortHashCode);
254 rd.data = &bob_hash;
255 rd.record_type = GNUNET_GNS_RECORD_PKEY;
256 rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY;
257
258 GNUNET_NAMESTORE_record_create (namestore_handle,
259 alice_key,
260 TEST_AUTHORITY_NAME,
261 &rd,
262 NULL,
263 NULL);
264
265 rd.data_size = sizeof (struct in_addr);
266 rd.data = sipserver;
267 rd.record_type = GNUNET_DNSPARSER_TYPE_A;
268 sig = GNUNET_NAMESTORE_create_signature(bob_key,
269 GNUNET_TIME_UNIT_FOREVER_ABS,
270 TEST_RECORD_NAME,
271 &rd, 1);
272 et.abs_value = rd.expiration_time;
273 GNUNET_NAMESTORE_record_put (namestore_handle,
274 &bob_pkey,
275 TEST_RECORD_NAME,
276 et,
277 1,
278 &rd,
279 sig,
280 NULL,
281 NULL);
282
283 rd.data_size = sizeof (struct srv_data)+strlen(TEST_SRV_NAME)+1;
284 srv_data->port = srv_port;
285 srv_data->prio = srv_prio;
286 srv_data->weight = srv_weight;
287 strcpy((char*)&srv_data[1], TEST_SRV_NAME);
288 rd.data = srv_data;
289 rd.record_type = GNUNET_GNS_RECORD_TYPE_SRV;
290 sig = GNUNET_NAMESTORE_create_signature(bob_key,
291 GNUNET_TIME_UNIT_FOREVER_ABS,
292 TEST_RECORD_NAME_SRV,
293 &rd, 1);
294 et.abs_value = rd.expiration_time;
295 GNUNET_NAMESTORE_record_put (namestore_handle,
296 &bob_pkey,
297 TEST_RECORD_NAME_SRV,
298 et,
299 1,
300 &rd,
301 sig,
302 &commence_testing,
303 NULL);
304 GNUNET_free(srv_data);
305 GNUNET_free(sipserver);
306 GNUNET_free(sig);
307 GNUNET_CRYPTO_rsa_key_free(bob_key);
308 GNUNET_CRYPTO_rsa_key_free(alice_key);
309}
310
311static void
312run (void *cls, char *const *args, const char *cfgfile,
313 const struct GNUNET_CONFIGURATION_Handle *c)
314{
315 cfg = c;
316 /* Get path from configuration file */
317 if (GNUNET_YES !=
318 GNUNET_CONFIGURATION_get_value_string (cfg, "paths", "servicehome",
319 &test_directory))
320 {
321 ok = 404;
322 return;
323 }
324
325
326 /* Set up a task to end testing if peer start fails */
327 die_task =
328 GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly,
329 "didn't start all daemons in reasonable amount of time!!!");
330
331 /* Start alice */
332 pg = GNUNET_TESTING_daemons_start(cfg, 1, 1, 1, TIMEOUT,
333 NULL, NULL, &do_lookup, NULL,
334 NULL, NULL, NULL);
335}
336
337static int
338check ()
339{
340 int ret;
341
342 /* Arguments for GNUNET_PROGRAM_run */
343 char *const argv[] = { "test-gns-simple-mx-lookup", /* Name to give running binary */
344 "-c",
345 "test_gns_simple_lookup.conf", /* Config file to use */
346#if VERBOSE
347 "-L", "DEBUG",
348#endif
349 NULL
350 };
351 struct GNUNET_GETOPT_CommandLineOption options[] = {
352 GNUNET_GETOPT_OPTION_END
353 };
354 /* Run the run function as a new program */
355 ret =
356 GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv,
357 "test-gns-simple-mx-lookup", "nohelp", options, &run,
358 &ok);
359 if (ret != GNUNET_OK)
360 {
361 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
362 "`test-gns-simple-mx-lookup': Failed with error code %d\n", ret);
363 }
364 return ok;
365}
366
367int
368main (int argc, char *argv[])
369{
370 int ret;
371
372 GNUNET_log_setup ("test-gns-simple-mx-lookup",
373#if VERBOSE
374 "DEBUG",
375#else
376 "WARNING",
377#endif
378 NULL);
379 ret = check ();
380 /**
381 * Need to remove base directory, subdirectories taken care
382 * of by the testing framework.
383 */
384 return ret;
385}
386
387/* end of test_gns_simple_mx_lookup.c */
diff --git a/src/include/gnunet_dnsparser_lib.h b/src/include/gnunet_dnsparser_lib.h
index 5a42baea6..a36996432 100644
--- a/src/include/gnunet_dnsparser_lib.h
+++ b/src/include/gnunet_dnsparser_lib.h
@@ -190,8 +190,7 @@ struct GNUNET_DNSPARSER_SrvRecord
190{ 190{
191 191
192 /** 192 /**
193 * Preference for this entry (lower value is higher preference). 193 * Service name without the underscore (!). Note that RFC 6335 clarifies the
194 * Without the underscore (!). Note that RFC 6335 clarifies the
195 * set of legal characters for service names. 194 * set of legal characters for service names.
196 */ 195 */
197 char *service; 196 char *service;
diff --git a/src/include/gnunet_gns_service.h b/src/include/gnunet_gns_service.h
index 86caf249e..521fcfadf 100644
--- a/src/include/gnunet_gns_service.h
+++ b/src/include/gnunet_gns_service.h
@@ -71,6 +71,7 @@ enum GNUNET_GNS_RecordType
71 GNUNET_GNS_RECORD_TYPE_NS = GNUNET_DNSPARSER_TYPE_NS, 71 GNUNET_GNS_RECORD_TYPE_NS = GNUNET_DNSPARSER_TYPE_NS,
72 GNUNET_GNS_RECORD_TYPE_CNAME = GNUNET_DNSPARSER_TYPE_CNAME, 72 GNUNET_GNS_RECORD_TYPE_CNAME = GNUNET_DNSPARSER_TYPE_CNAME,
73 GNUNET_GNS_RECORD_TYPE_SOA = GNUNET_DNSPARSER_TYPE_SOA, 73 GNUNET_GNS_RECORD_TYPE_SOA = GNUNET_DNSPARSER_TYPE_SOA,
74 GNUNET_GNS_RECORD_TYPE_SRV = GNUNET_DNSPARSER_TYPE_SRV,
74 GNUNET_GNS_RECORD_TYPE_PTR = GNUNET_DNSPARSER_TYPE_PTR, 75 GNUNET_GNS_RECORD_TYPE_PTR = GNUNET_DNSPARSER_TYPE_PTR,
75 GNUNET_GNS_RECORD_MX = GNUNET_DNSPARSER_TYPE_MX, 76 GNUNET_GNS_RECORD_MX = GNUNET_DNSPARSER_TYPE_MX,
76 GNUNET_GNS_RECORD_TXT = GNUNET_DNSPARSER_TYPE_TXT, 77 GNUNET_GNS_RECORD_TXT = GNUNET_DNSPARSER_TYPE_TXT,