aboutsummaryrefslogtreecommitdiff
path: root/src/gns/gnunet-service-gns_resolver.c
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2012-06-22 00:37:08 +0000
committerMartin Schanzenbach <mschanzenbach@posteo.de>2012-06-22 00:37:08 +0000
commiteec111fe95456619682d12859685d326ca161e46 (patch)
tree3e1e945af4506cf5d3a0da611ce6dfc5865c0e68 /src/gns/gnunet-service-gns_resolver.c
parent4e7a535cc04df4eef21dc1db39d782a3365e9df1 (diff)
downloadgnunet-eec111fe95456619682d12859685d326ca161e46.tar.gz
gnunet-eec111fe95456619682d12859685d326ca161e46.zip
Added proper SRV handling and test
Diffstat (limited to 'src/gns/gnunet-service-gns_resolver.c')
-rw-r--r--src/gns/gnunet-service-gns_resolver.c221
1 files changed, 142 insertions, 79 deletions
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);