From 66d90f54243ad0ca5953a3aba9ab8aaca159d704 Mon Sep 17 00:00:00 2001 From: Martin Schanzenbach Date: Fri, 22 Jun 2012 12:54:34 +0000 Subject: [PATCH] -make record data parsing easier for namestore,gns with dnsparser structs --- src/dns/dnsparser.c | 150 +------------------- src/dns/dnsparser.h | 193 ++++++++++++++++++++++++++ src/gns/gnunet-service-gns_resolver.c | 109 ++++++--------- src/namestore/namestore_common.c | 108 +++++++------- 4 files changed, 293 insertions(+), 267 deletions(-) create mode 100644 src/dns/dnsparser.h diff --git a/src/dns/dnsparser.c b/src/dns/dnsparser.c index 8b8cd22fd..c2afbdf3a 100644 --- a/src/dns/dnsparser.c +++ b/src/dns/dnsparser.c @@ -27,157 +27,9 @@ #include "platform.h" #include "gnunet_util_lib.h" #include "gnunet_dnsparser_lib.h" +#include "dnsparser.h" -GNUNET_NETWORK_STRUCT_BEGIN - -/* FIXME: replace this one with the one from tcpip_tun.h!? */ -/** - * Head of a any DNS message. - */ -struct GNUNET_TUN_DnsHeader -{ - /** - * Request/response ID. (NBO) - */ - uint16_t id GNUNET_PACKED; - - /** - * Flags for the operation. - */ - struct GNUNET_DNSPARSER_Flags flags; - - /** - * number of questions (NBO) - */ - uint16_t query_count GNUNET_PACKED; - - /** - * number of answers (NBO) - */ - uint16_t answer_rcount GNUNET_PACKED; - - /** - * number of authority-records (NBO) - */ - uint16_t authority_rcount GNUNET_PACKED; - - /** - * number of additional records (NBO) - */ - uint16_t additional_rcount GNUNET_PACKED; -}; - - -/** - * DNS query prefix. - */ -struct query_line -{ - /** - * Desired type (GNUNET_DNSPARSER_TYPE_XXX). (NBO) - */ - uint16_t type GNUNET_PACKED; - - /** - * Desired class (usually GNUNET_DNSPARSER_CLASS_INTERNET). (NBO) - */ - uint16_t class GNUNET_PACKED; -}; - - -/** - * General DNS record prefix. - */ -struct record_line -{ - /** - * Record type (GNUNET_DNSPARSER_TYPE_XXX). (NBO) - */ - uint16_t type GNUNET_PACKED; - - /** - * Record class (usually GNUNET_DNSPARSER_CLASS_INTERNET). (NBO) - */ - uint16_t class GNUNET_PACKED; - - /** - * Expiration for the record (in seconds). (NBO) - */ - uint32_t ttl GNUNET_PACKED; - - /** - * Number of bytes of data that follow. (NBO) - */ - uint16_t data_len GNUNET_PACKED; -}; - - -/** - * Payload of DNS SOA record (header). - */ -struct soa_data -{ - /** - * The version number of the original copy of the zone. (NBO) - */ - uint32_t serial GNUNET_PACKED; - - /** - * Time interval before the zone should be refreshed. (NBO) - */ - uint32_t refresh GNUNET_PACKED; - - /** - * Time interval that should elapse before a failed refresh should - * be retried. (NBO) - */ - uint32_t retry GNUNET_PACKED; - - /** - * Time value that specifies the upper limit on the time interval - * that can elapse before the zone is no longer authoritative. (NBO) - */ - uint32_t expire GNUNET_PACKED; - - /** - * The bit minimum TTL field that should be exported with any RR - * from this zone. (NBO) - */ - uint32_t minimum GNUNET_PACKED; -}; - - -/** - * Payload of DNS SRV record (header). - */ -struct srv_data -{ - - /** - * Preference for this entry (lower value is higher preference). Clients - * will contact hosts from the lowest-priority group first and fall back - * to higher priorities if the low-priority entries are unavailable. (NBO) - */ - uint16_t prio GNUNET_PACKED; - - /** - * Relative weight for records with the same priority. Clients will use - * the hosts of the same (lowest) priority with a probability proportional - * to the weight given. (NBO) - */ - uint16_t weight GNUNET_PACKED; - - /** - * TCP or UDP port of the service. (NBO) - */ - uint16_t port GNUNET_PACKED; - - /* followed by 'target' name */ -}; - -GNUNET_NETWORK_STRUCT_END - /** * Parse name inside of a DNS query or record. diff --git a/src/dns/dnsparser.h b/src/dns/dnsparser.h new file mode 100644 index 000000000..e3ab622c7 --- /dev/null +++ b/src/dns/dnsparser.h @@ -0,0 +1,193 @@ +/* + This file is part of GNUnet + (C) 2010, 2011, 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/** + * @file dns/dnsparser.h + * @brief helper library to parse DNS packets. + * @author Philipp Toelke + * @author Christian Grothoff + * @author Martin Schanzenbach + */ +GNUNET_NETWORK_STRUCT_BEGIN + +/* FIXME: replace this one with the one from tcpip_tun.h!? */ +/** + * Head of a any DNS message. + */ +struct GNUNET_TUN_DnsHeader +{ + /** + * Request/response ID. (NBO) + */ + uint16_t id GNUNET_PACKED; + + /** + * Flags for the operation. + */ + struct GNUNET_DNSPARSER_Flags flags; + + /** + * number of questions (NBO) + */ + uint16_t query_count GNUNET_PACKED; + + /** + * number of answers (NBO) + */ + uint16_t answer_rcount GNUNET_PACKED; + + /** + * number of authority-records (NBO) + */ + uint16_t authority_rcount GNUNET_PACKED; + + /** + * number of additional records (NBO) + */ + uint16_t additional_rcount GNUNET_PACKED; +}; + + +/** + * DNS query prefix. + */ +struct query_line +{ + /** + * Desired type (GNUNET_DNSPARSER_TYPE_XXX). (NBO) + */ + uint16_t type GNUNET_PACKED; + + /** + * Desired class (usually GNUNET_DNSPARSER_CLASS_INTERNET). (NBO) + */ + uint16_t class GNUNET_PACKED; +}; + + +/** + * General DNS record prefix. + */ +struct record_line +{ + /** + * Record type (GNUNET_DNSPARSER_TYPE_XXX). (NBO) + */ + uint16_t type GNUNET_PACKED; + + /** + * Record class (usually GNUNET_DNSPARSER_CLASS_INTERNET). (NBO) + */ + uint16_t class GNUNET_PACKED; + + /** + * Expiration for the record (in seconds). (NBO) + */ + uint32_t ttl GNUNET_PACKED; + + /** + * Number of bytes of data that follow. (NBO) + */ + uint16_t data_len GNUNET_PACKED; +}; + + +/** + * Payload of DNS SOA record (header). + */ +struct soa_data +{ + /** + * The version number of the original copy of the zone. (NBO) + */ + uint32_t serial GNUNET_PACKED; + + /** + * Time interval before the zone should be refreshed. (NBO) + */ + uint32_t refresh GNUNET_PACKED; + + /** + * Time interval that should elapse before a failed refresh should + * be retried. (NBO) + */ + uint32_t retry GNUNET_PACKED; + + /** + * Time value that specifies the upper limit on the time interval + * that can elapse before the zone is no longer authoritative. (NBO) + */ + uint32_t expire GNUNET_PACKED; + + /** + * The bit minimum TTL field that should be exported with any RR + * from this zone. (NBO) + */ + uint32_t minimum GNUNET_PACKED; +}; + + +/** + * Payload of DNS SRV record (header). + */ +struct srv_data +{ + + /** + * Preference for this entry (lower value is higher preference). Clients + * will contact hosts from the lowest-priority group first and fall back + * to higher priorities if the low-priority entries are unavailable. (NBO) + */ + uint16_t prio GNUNET_PACKED; + + /** + * Relative weight for records with the same priority. Clients will use + * the hosts of the same (lowest) priority with a probability proportional + * to the weight given. (NBO) + */ + uint16_t weight GNUNET_PACKED; + + /** + * TCP or UDP port of the service. (NBO) + */ + uint16_t port GNUNET_PACKED; + + /* followed by 'target' name */ +}; + +/** + * Payload of GNS VPN record + */ +struct vpn_data +{ + /** + * The protocol to use + */ + uint16_t proto; + + /** + * The peer to contact + */ + struct GNUNET_HashCode peer; + + /* followed by the servicename */ +}; + +GNUNET_NETWORK_STRUCT_END diff --git a/src/gns/gnunet-service-gns_resolver.c b/src/gns/gnunet-service-gns_resolver.c index bbeea86f4..eac0a139f 100644 --- a/src/gns/gnunet-service-gns_resolver.c +++ b/src/gns/gnunet-service-gns_resolver.c @@ -35,6 +35,7 @@ #include "gnunet_dns_service.h" #include "gnunet_resolver_service.h" #include "gnunet_dnsparser_lib.h" +#include "../dns/dnsparser.h" #include "gnunet_gns_service.h" #include "block_gns.h" #include "gns.h" @@ -1811,14 +1812,10 @@ resolve_record_vpn (struct ResolverHandle *rh, int rd_count, const struct GNUNET_NAMESTORE_RecordData *rd) { - int af; - int proto; - struct GNUNET_HashCode peer_id; - struct GNUNET_CRYPTO_HashAsciiEncoded s_pid; + struct RecordLookupHandle *rlh = rh->proc_cls; struct GNUNET_HashCode serv_desc; - struct GNUNET_CRYPTO_HashAsciiEncoded s_sd; - char* pos; - size_t len = (sizeof (uint32_t) * 2) + (sizeof (struct GNUNET_HashCode) * 2); + struct vpn_data* vpn; + int af; /* We cancel here as to not include the ns lookup in the timeout */ if (rh->timeout_task != GNUNET_SCHEDULER_NO_TASK) @@ -1836,37 +1833,12 @@ resolve_record_vpn (struct ResolverHandle *rh, rh->priv_key); } - /* Extracting VPN information FIXME rd parsing with NS API?*/ - if (len != rd->data_size) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC_VPN-%llu: Error parsing VPN RR!\n", - rh->id); - finish_lookup (rh, rh->proc_cls, 0, NULL); - free_resolver_handle (rh); - return; - } + vpn = (struct vpn_data*)rd; - pos = (char*)rd; - memcpy (&af, pos, sizeof (uint32_t)); - pos += sizeof (uint32_t); - memcpy (&proto, pos, sizeof (uint32_t)); - pos += sizeof (uint32_t); - memcpy (&s_pid, pos, sizeof (struct GNUNET_HashCode)); - pos += sizeof (struct GNUNET_HashCode); - memcpy (&s_sd, pos, sizeof (struct GNUNET_HashCode)); - - if ((GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((char*)&s_pid, &peer_id)) || - (GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((char*)&s_sd, &serv_desc))) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "GNS_PHASE_REC_VPN-%llu: Error parsing VPN RR hashes!\n", - rh->id); - finish_lookup (rh, rh->proc_cls, 0, NULL); - free_resolver_handle (rh); - return; - } + GNUNET_CRYPTO_hash ((char*)&vpn[1], + strlen ((char*)&vpn[1]), + &serv_desc); rh->proc = &handle_record_vpn; @@ -1879,11 +1851,16 @@ resolve_record_vpn (struct ResolverHandle *rh, free_resolver_handle (rh); return; } + + if (rlh->record_type == GNUNET_GNS_RECORD_TYPE_A) + af = AF_INET; + else + af = AF_INET6; //FIXME timeout?? rh->vpn_handle = GNUNET_VPN_redirect_to_peer (vpn_handle, - af, proto, - (struct GNUNET_PeerIdentity*)&peer_id, + af, ntohs (vpn->proto), + (struct GNUNET_PeerIdentity *)&vpn->peer, &serv_desc, GNUNET_NO, //nac GNUNET_TIME_UNIT_FOREVER_ABS, //FIXME @@ -2351,7 +2328,7 @@ process_delegation_result_dht(void* cls, static void -expand_plus(char** dest, char* src, char* repl) +expand_plus(char* dest, char* src, char* repl) { char* pos; unsigned int s_len = strlen(src)+1; @@ -2365,7 +2342,7 @@ expand_plus(char** dest, char* src, char* repl) "GNS_POSTPROCESS: %s to short\n", src); /* no postprocessing */ - memcpy(*dest, src, s_len+1); + memcpy(dest, src, s_len+1); return; } @@ -2373,17 +2350,17 @@ expand_plus(char** dest, char* src, char* repl) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "GNS_POSTPROCESS: Expanding .+ in %s\n", src); - memset(*dest, 0, s_len+strlen(repl)+strlen(GNUNET_GNS_TLD)); - strcpy(*dest, src); - pos = *dest+s_len-2; + memset(dest, 0, s_len+strlen(repl)+strlen(GNUNET_GNS_TLD)); + strcpy(dest, src); + pos = dest+s_len-2; strcpy(pos, repl); pos += strlen(repl); GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GNS_POSTPROCESS: Expanded to %s\n", *dest); + "GNS_POSTPROCESS: Expanded to %s\n", dest); } else { - memcpy(*dest, src, s_len+1); + memcpy(dest, src, s_len+1); } } @@ -2401,6 +2378,10 @@ finish_lookup(struct ResolverHandle *rh, char new_mx_data[MAX_MX_LENGTH]; char new_soa_data[MAX_SOA_LENGTH]; char new_srv_data[MAX_SRV_LENGTH]; + struct srv_data *old_srv; + struct srv_data *new_srv; + struct soa_data *old_soa; + struct soa_data *new_soa; struct GNUNET_NAMESTORE_RecordData p_rd[rd_count]; char* repl_string; char* pos; @@ -2448,7 +2429,7 @@ finish_lookup(struct ResolverHandle *rh, memcpy (new_mx_data, (char*)rd[i].data, sizeof(uint16_t)); offset = sizeof(uint16_t); pos = new_mx_data+offset; - expand_plus(&pos, (char*)rd[i].data+sizeof(uint16_t), + expand_plus(pos, (char*)rd[i].data+sizeof(uint16_t), repl_string); offset += strlen(new_mx_data+sizeof(uint16_t))+1; p_rd[i].data = new_mx_data; @@ -2459,34 +2440,36 @@ finish_lookup(struct ResolverHandle *rh, /* * Prio, weight and port */ - memcpy (new_srv_data, (char*)rd[i].data, sizeof (uint16_t) * 3); - offset = sizeof (uint16_t) * 3; - pos = new_srv_data+offset; - expand_plus(&pos, (char*)rd[i].data+(sizeof(uint16_t)*3), + new_srv = (struct srv_data*)new_srv_data; + old_srv = (struct srv_data*)rd[i].data; + new_srv->prio = old_srv->prio; + new_srv->weight = old_srv->weight; + new_srv->port = old_srv->port; + expand_plus((char*)&new_srv[1], (char*)&old_srv[1], repl_string); - offset += strlen(new_srv_data+(sizeof(uint16_t)*3))+1; p_rd[i].data = new_srv_data; - p_rd[i].data_size = offset; + p_rd[i].data_size = sizeof (struct srv_data) + strlen ((char*)&new_srv[1]) + 1; } else if (rd[i].record_type == GNUNET_GNS_RECORD_TYPE_SOA) { /* expand mname and rname */ - pos = new_soa_data; - expand_plus(&pos, (char*)rd[i].data, repl_string); - offset = strlen(new_soa_data)+1; - pos = new_soa_data+offset; - expand_plus(&pos, (char*)rd[i].data+offset, repl_string); - offset += strlen(new_soa_data+offset)+1; - /* cpy the 4 numbers serial refresh retry and expire */ - memcpy(new_soa_data+offset, (char*)rd[i].data+offset, sizeof(uint32_t)*5); - offset += sizeof(uint32_t)*5; - p_rd[i].data_size = offset; + old_soa = (struct soa_data*)rd[i].data; + new_soa = (struct soa_data*)new_soa_data; + memcpy (new_soa, old_soa, sizeof (struct soa_data)); + expand_plus((char*)&new_soa[1], (char*)&old_soa[1], repl_string); + offset = strlen ((char*)&new_soa[1]) + 1; + expand_plus((char*)&new_soa[1] + offset, + (char*)&old_soa[1] + strlen ((char*)&old_soa[1]) + 1, + repl_string); + p_rd[i].data_size = sizeof (struct soa_data) + + offset + + strlen ((char*)&new_soa[1] + offset); p_rd[i].data = new_soa_data; } else { pos = new_rr_data; - expand_plus(&pos, (char*)rd[i].data, repl_string); + expand_plus(pos, (char*)rd[i].data, repl_string); p_rd[i].data_size = strlen(new_rr_data)+1; p_rd[i].data = new_rr_data; } diff --git a/src/namestore/namestore_common.c b/src/namestore/namestore_common.c index 996259b51..af7eee04c 100644 --- a/src/namestore/namestore_common.c +++ b/src/namestore/namestore_common.c @@ -32,6 +32,7 @@ #include "gnunet_arm_service.h" #include "gnunet_namestore_service.h" #include "gnunet_dnsparser_lib.h" +#include "../dns/dnsparser.h" #include "namestore.h" @@ -322,19 +323,13 @@ GNUNET_NAMESTORE_value_to_string (uint32_t type, char* result; char* soa_rname; char* soa_mname; - uint32_t* soa_data; - uint32_t soa_serial; - uint32_t soa_refresh; - uint32_t soa_retry; - uint32_t soa_expire; - uint32_t soa_min; - uint32_t *af; - uint32_t *proto; + struct soa_data *soa; + + struct vpn_data *vpn; char* vpn_str; - struct GNUNET_HashCode *h_peer; - struct GNUNET_HashCode *h_serv; + char* srv_str; struct GNUNET_CRYPTO_HashAsciiEncoded s_peer; - struct GNUNET_CRYPTO_HashAsciiEncoded s_serv; + struct srv_data *srv; switch (type) { @@ -351,17 +346,13 @@ GNUNET_NAMESTORE_value_to_string (uint32_t type, case GNUNET_DNSPARSER_TYPE_CNAME: return GNUNET_strndup (data, data_size); case GNUNET_DNSPARSER_TYPE_SOA: - soa_rname = (char*)data; - soa_mname = (char*)data+strlen(soa_rname)+1; - soa_data = (uint32_t*)(soa_mname+strlen(soa_mname)+1); - soa_serial = ntohl(soa_data[0]); - soa_refresh = ntohl(soa_data[1]); - soa_retry = ntohl(soa_data[2]); - soa_expire = ntohl(soa_data[3]); - soa_min = ntohl(soa_data[4]); + soa = (struct soa_data*)data; + soa_rname = (char*)&soa[1]; + soa_mname = (char*)&soa[1]+strlen(soa_rname)+1; if (GNUNET_asprintf(&result, "rname=%s mname=%s %lu,%lu,%lu,%lu,%lu", soa_rname, soa_mname, - soa_serial, soa_refresh, soa_retry, soa_expire, soa_min)) + ntohl (soa->serial), ntohl (soa->refresh), + ntohl (soa->retry), ntohl (soa->expire), ntohl (soa->minimum))) return result; else return NULL; @@ -393,16 +384,25 @@ GNUNET_NAMESTORE_value_to_string (uint32_t type, case GNUNET_NAMESTORE_TYPE_LEHO: return GNUNET_strndup (data, data_size); case GNUNET_NAMESTORE_TYPE_VPN: - af = (uint32_t*)data; - proto = (uint32_t*)((char*)af + sizeof (uint32_t)); - h_peer = (struct GNUNET_HashCode*)((char*)proto + sizeof (struct GNUNET_HashCode)); - h_serv = (struct GNUNET_HashCode*)((char*)h_peer + sizeof (struct GNUNET_HashCode)); - - GNUNET_CRYPTO_hash_to_enc (h_peer, &s_peer); - GNUNET_CRYPTO_hash_to_enc (h_serv, &s_serv); - if (GNUNET_OK != GNUNET_asprintf (&vpn_str, "%d:%d:%s:%s", af, proto, (char*)&s_peer, (char*)&s_serv)) + vpn = (struct vpn_data*)data; + + GNUNET_CRYPTO_hash_to_enc (&vpn->peer, &s_peer); + if (GNUNET_OK != GNUNET_asprintf (&vpn_str, "%d:%s:%s", + vpn->proto, + (char*)&s_peer, + (char*)&vpn[1])) return NULL; return vpn_str; + case GNUNET_DNSPARSER_TYPE_SRV: + srv = (struct srv_data*)data; + + if (GNUNET_OK != GNUNET_asprintf (&srv_str, "%d:%d:%d:%s", + ntohs (srv->prio), + ntohs (srv->weight), + ntohs (srv->port), + (char*)&srv[1])) + return NULL; + return srv_str; default: GNUNET_break (0); } @@ -432,7 +432,7 @@ GNUNET_NAMESTORE_string_to_value (uint32_t type, struct GNUNET_CRYPTO_ShortHashCode pkey; uint16_t mx_pref; uint16_t mx_pref_n; - uint32_t soa_data[5]; + struct soa_data *soa; char result[253]; char soa_rname[63]; char soa_mname[63]; @@ -441,12 +441,10 @@ GNUNET_NAMESTORE_string_to_value (uint32_t type, uint32_t soa_retry; uint32_t soa_expire; uint32_t soa_min; - struct GNUNET_HashCode *h_peer; - struct GNUNET_HashCode *h_serv; struct GNUNET_CRYPTO_HashAsciiEncoded s_peer; - struct GNUNET_CRYPTO_HashAsciiEncoded s_serv; - uint32_t* af; - uint32_t* proto; + char s_serv[253]; + struct vpn_data* vpn; + uint16_t proto; switch (type) { @@ -475,17 +473,16 @@ GNUNET_NAMESTORE_string_to_value (uint32_t type, != 7) return GNUNET_SYSERR; - *data_size = sizeof (soa_data)+strlen(soa_rname)+strlen(soa_mname)+2; + *data_size = sizeof (struct soa_data)+strlen(soa_rname)+strlen(soa_mname)+2; *data = GNUNET_malloc (*data_size); - soa_data[0] = htonl(soa_serial); - soa_data[1] = htonl(soa_refresh); - soa_data[2] = htonl(soa_retry); - soa_data[3] = htonl(soa_expire); - soa_data[4] = htonl(soa_min); - strcpy(*data, soa_rname); - strcpy(*data+strlen(*data)+1, soa_mname); - memcpy(*data+strlen(*data)+1+strlen(soa_mname)+1, - soa_data, sizeof(soa_data)); + soa = (struct soa_data*)*data; + soa->serial = htonl(soa_serial); + soa->refresh = htonl(soa_refresh); + soa->retry = htonl(soa_retry); + soa->expire = htonl(soa_expire); + soa->minimum = htonl(soa_min); + strcpy((char*)&soa[1], soa_rname); + strcpy((char*)&soa[1]+strlen(*data)+1, soa_mname); return GNUNET_OK; case GNUNET_DNSPARSER_TYPE_PTR: @@ -530,25 +527,26 @@ GNUNET_NAMESTORE_string_to_value (uint32_t type, return GNUNET_OK; case GNUNET_NAMESTORE_TYPE_VPN: - *data_size = sizeof (uint32_t) * 2; - *data_size += sizeof (struct GNUNET_HashCode) * 2; - *data = GNUNET_malloc (*data_size); - af = (uint32_t*)(*data); - proto = (uint32_t*) ((char*)af + sizeof (uint32_t)); - h_peer = (struct GNUNET_HashCode*)((char*)proto + sizeof (uint32_t)); - h_serv = (struct GNUNET_HashCode*)((char*)h_peer + sizeof (struct GNUNET_HashCode)); - if (4 != SSCANF (s,"%d:%d:%s:%s", - af, proto, (char*)&s_peer, (char*)&s_serv)) + if (4 != SSCANF (s,"%hu:%s:%s", + &proto, (char*)&s_peer, s_serv)) { return GNUNET_SYSERR; } - if ((GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((char*)&s_peer, h_peer)) || - (GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((char*)&s_serv, h_serv))) + *data_size = sizeof (struct vpn_data) + strlen (s_serv) + 1; + + *data = GNUNET_malloc (*data_size); + + vpn = (struct vpn_data*)*data; + + if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((char*)&s_peer, &vpn->peer)) { GNUNET_free (*data); return GNUNET_SYSERR; } + + vpn->proto = htons (proto); + strcpy ((char*)&vpn[1], s_serv); return GNUNET_OK; default: GNUNET_break (0); -- 2.25.1