aboutsummaryrefslogtreecommitdiff
path: root/src/vpn/gnunet-service-dns.c
diff options
context:
space:
mode:
authorPhilipp Tölke <toelke@in.tum.de>2011-10-26 07:13:23 +0000
committerPhilipp Tölke <toelke@in.tum.de>2011-10-26 07:13:23 +0000
commit913f88d980ef4fcc4153336042387a17ad8e428b (patch)
treef7bc0d3e34dc0b84810dd44a0025cfea69e9aa95 /src/vpn/gnunet-service-dns.c
parent9095e6a2fc69654f993c37c0e5e4159dbd88028d (diff)
downloadgnunet-913f88d980ef4fcc4153336042387a17ad8e428b.tar.gz
gnunet-913f88d980ef4fcc4153336042387a17ad8e428b.zip
handle dns over ipv6 and 6-to-4 and 4-to-6
Diffstat (limited to 'src/vpn/gnunet-service-dns.c')
-rw-r--r--src/vpn/gnunet-service-dns.c386
1 files changed, 274 insertions, 112 deletions
diff --git a/src/vpn/gnunet-service-dns.c b/src/vpn/gnunet-service-dns.c
index 81f5cad98..38ce3c147 100644
--- a/src/vpn/gnunet-service-dns.c
+++ b/src/vpn/gnunet-service-dns.c
@@ -50,6 +50,7 @@ struct GNUNET_CONNECTION_TransmitHandle *server_notify;
50 * sent through gnunet. The port of this socket will not be hijacked. 50 * sent through gnunet. The port of this socket will not be hijacked.
51 */ 51 */
52static struct GNUNET_NETWORK_Handle *dnsout; 52static struct GNUNET_NETWORK_Handle *dnsout;
53static struct GNUNET_NETWORK_Handle *dnsout6;
53 54
54/** 55/**
55 * The port bound to the socket dnsout 56 * The port bound to the socket dnsout
@@ -90,8 +91,9 @@ static struct
90 unsigned valid:1; 91 unsigned valid:1;
91 struct GNUNET_SERVER_Client *client; 92 struct GNUNET_SERVER_Client *client;
92 struct GNUNET_MESH_Tunnel *tunnel; 93 struct GNUNET_MESH_Tunnel *tunnel;
93 uint32_t local_ip; 94 char local_ip[16];
94 uint32_t remote_ip; 95 char remote_ip[16];
96 char addrlen;
95 uint16_t local_port; 97 uint16_t local_port;
96 char *name; 98 char *name;
97 uint8_t namelen; 99 uint8_t namelen;
@@ -485,9 +487,9 @@ receive_mesh_answer (void *cls
485 memcpy (answer->pkt.addr, pdns->answers[0]->data, 487 memcpy (answer->pkt.addr, pdns->answers[0]->data,
486 ntohs (pdns->answers[0]->data_len)); 488 ntohs (pdns->answers[0]->data_len));
487 489
488 answer->pkt.from = query_states[dns->s.id].remote_ip; 490 memcpy(answer->pkt.from, query_states[dns->s.id].remote_ip, query_states[dns->s.id].addrlen);
489 491 memcpy(answer->pkt.to, query_states[dns->s.id].local_ip, query_states[dns->s.id].addrlen);
490 answer->pkt.to = query_states[dns->s.id].local_ip; 492 answer->pkt.addrlen = query_states[dns->s.id].addrlen;
491 answer->pkt.dst_port = query_states[dns->s.id].local_port; 493 answer->pkt.dst_port = query_states[dns->s.id].local_port;
492 494
493 struct dns_pkt *dpkt = (struct dns_pkt *) answer->pkt.data; 495 struct dns_pkt *dpkt = (struct dns_pkt *) answer->pkt.data;
@@ -589,9 +591,9 @@ send_rev_query (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
589 answer->pkt.hdr.size = htons (len); 591 answer->pkt.hdr.size = htons (len);
590 answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_REV; 592 answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_REV;
591 593
592 answer->pkt.from = query_states[id].remote_ip; 594 memcpy(answer->pkt.from, query_states[id].remote_ip, query_states[id].addrlen);
595 memcpy(answer->pkt.to, query_states[id].local_ip, query_states[id].addrlen);
593 596
594 answer->pkt.to = query_states[id].local_ip;
595 answer->pkt.dst_port = query_states[id].local_port; 597 answer->pkt.dst_port = query_states[id].local_port;
596 598
597 struct dns_pkt *dpkt = (struct dns_pkt *) answer->pkt.data; 599 struct dns_pkt *dpkt = (struct dns_pkt *) answer->pkt.data;
@@ -700,9 +702,9 @@ receive_dht (void *cls, struct GNUNET_TIME_Absolute exp
700 memcpy (&answer->pkt.service_descr.ports, &rec->ports, 702 memcpy (&answer->pkt.service_descr.ports, &rec->ports,
701 sizeof (answer->pkt.service_descr.ports)); 703 sizeof (answer->pkt.service_descr.ports));
702 704
703 answer->pkt.from = query_states[id].remote_ip; 705 memcpy(answer->pkt.from, query_states[id].remote_ip, query_states[id].addrlen);
706 memcpy(answer->pkt.to, query_states[id].local_ip, query_states[id].addrlen);
704 707
705 answer->pkt.to = query_states[id].local_ip;
706 answer->pkt.dst_port = query_states[id].local_port; 708 answer->pkt.dst_port = query_states[id].local_port;
707 709
708 struct dns_pkt *dpkt = (struct dns_pkt *) answer->pkt.data; 710 struct dns_pkt *dpkt = (struct dns_pkt *) answer->pkt.data;
@@ -784,9 +786,10 @@ receive_query (void *cls
784 786
785 query_states[dns->s.id].valid = GNUNET_YES; 787 query_states[dns->s.id].valid = GNUNET_YES;
786 query_states[dns->s.id].client = client; 788 query_states[dns->s.id].client = client;
787 query_states[dns->s.id].local_ip = pkt->orig_from; 789 memcpy(query_states[dns->s.id].local_ip, pkt->orig_from, pkt->addrlen);
790 query_states[dns->s.id].addrlen = pkt->addrlen;
788 query_states[dns->s.id].local_port = pkt->src_port; 791 query_states[dns->s.id].local_port = pkt->src_port;
789 query_states[dns->s.id].remote_ip = pkt->orig_to; 792 memcpy(query_states[dns->s.id].remote_ip, pkt->orig_to, pkt->addrlen);
790 query_states[dns->s.id].namelen = strlen ((char *) dns->data) + 1; 793 query_states[dns->s.id].namelen = strlen ((char *) dns->data) + 1;
791 if (query_states[dns->s.id].name != NULL) 794 if (query_states[dns->s.id].name != NULL)
792 GNUNET_free (query_states[dns->s.id].name); 795 GNUNET_free (query_states[dns->s.id].name);
@@ -883,27 +886,56 @@ receive_query (void *cls
883 } 886 }
884 } 887 }
885 888
886 char *virt_dns; 889 unsigned char virt_dns_bytes[16];
887 unsigned int virt_dns_bytes;
888 890
889 if (GNUNET_SYSERR == 891 if (pkt->addrlen == 4)
890 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "VIRTDNS", &virt_dns)) 892 {
891 { 893 char *virt_dns;
892 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
893 "No entry 'VIRTDNS' in configuration!\n");
894 exit (1);
895 }
896 894
897 if (1 != inet_pton (AF_INET, virt_dns, &virt_dns_bytes)) 895 if (GNUNET_SYSERR ==
898 { 896 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "VIRTDNS", &virt_dns))
899 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error parsing 'VIRTDNS': %s; %m!\n", 897 {
900 virt_dns); 898 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
901 exit (1); 899 "No entry 'VIRTDNS' in configuration!\n");
902 } 900 exit (1);
901 }
903 902
904 GNUNET_free (virt_dns); 903 if (1 != inet_pton (AF_INET, virt_dns, &virt_dns_bytes))
904 {
905 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error parsing 'VIRTDNS': %s; %m!\n",
906 virt_dns);
907 exit (1);
908 }
909
910 GNUNET_free (virt_dns);
911 }
912 else if (pkt->addrlen == 16)
913 {
914 char *virt_dns;
915
916 if (GNUNET_SYSERR ==
917 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "VIRTDNS6", &virt_dns))
918 {
919 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
920 "No entry 'VIRTDNS6' in configuration!\n");
921 exit (1);
922 }
923
924 if (1 != inet_pton (AF_INET6, virt_dns, &virt_dns_bytes))
925 {
926 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error parsing 'VIRTDNS6': %s; %m!\n",
927 virt_dns);
928 exit (1);
929 }
930
931 GNUNET_free (virt_dns);
932 }
933 else
934 {
935 GNUNET_assert(0);
936 }
905 937
906 if (virt_dns_bytes == pkt->orig_to) 938 if (memcmp(virt_dns_bytes,pkt->orig_to, pkt->addrlen) == 0)
907 { 939 {
908 /* This is a packet that was sent directly to the virtual dns-server 940 /* This is a packet that was sent directly to the virtual dns-server
909 * 941 *
@@ -958,17 +990,32 @@ receive_query (void *cls
958 990
959 991
960 /* The query should be sent to the network */ 992 /* The query should be sent to the network */
993 if (pkt->addrlen == 4)
994 {
995 struct sockaddr_in dest;
961 996
962 struct sockaddr_in dest; 997 memset (&dest, 0, sizeof dest);
998 dest.sin_port = htons (53);
999 memcpy(&dest.sin_addr.s_addr, pkt->orig_to, pkt->addrlen);
963 1000
964 memset (&dest, 0, sizeof dest); 1001 GNUNET_NETWORK_socket_sendto (dnsout, dns,
965 dest.sin_port = htons (53); 1002 ntohs (pkt->hdr.size) -
966 dest.sin_addr.s_addr = pkt->orig_to; 1003 sizeof (struct query_packet) + 1,
1004 (struct sockaddr *) &dest, sizeof dest);
1005 }
1006 else if (pkt->addrlen == 16)
1007 {
1008 struct sockaddr_in6 dest;
967 1009
968 GNUNET_NETWORK_socket_sendto (dnsout, dns, 1010 memset (&dest, 0, sizeof dest);
969 ntohs (pkt->hdr.size) - 1011 dest.sin6_port = htons (53);
970 sizeof (struct query_packet) + 1, 1012 memcpy(&dest.sin6_addr, pkt->orig_to, pkt->addrlen);
971 (struct sockaddr *) &dest, sizeof dest); 1013
1014 GNUNET_NETWORK_socket_sendto (dnsout6, dns,
1015 ntohs (pkt->hdr.size) -
1016 sizeof (struct query_packet) + 1,
1017 (struct sockaddr *) &dest, sizeof dest);
1018 }
972 1019
973outfree: 1020outfree:
974 free_parsed_dns_packet (pdns); 1021 free_parsed_dns_packet (pdns);
@@ -980,6 +1027,39 @@ out:
980static void 1027static void
981read_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); 1028read_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
982 1029
1030static void
1031read_response6 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
1032
1033static int
1034open_port6 ()
1035{
1036 struct sockaddr_in6 addr;
1037
1038 dnsout6 = GNUNET_NETWORK_socket_create (AF_INET6, SOCK_DGRAM, 0);
1039 if (dnsout6 == NULL)
1040 {
1041 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not create socket: %m\n");
1042 return GNUNET_SYSERR;
1043 }
1044 memset (&addr, 0, sizeof (struct sockaddr_in6));
1045
1046 addr.sin6_family = AF_INET6;
1047 int err = GNUNET_NETWORK_socket_bind (dnsout6,
1048 (struct sockaddr *) &addr,
1049 sizeof (struct sockaddr_in6));
1050
1051 if (err != GNUNET_OK)
1052 {
1053 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not bind a port: %m\n");
1054 return GNUNET_SYSERR;
1055 }
1056
1057 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, dnsout6,
1058 &read_response6, NULL);
1059
1060 return GNUNET_YES;
1061}
1062
983static int 1063static int
984open_port () 1064open_port ()
985{ 1065{
@@ -1018,6 +1098,57 @@ open_port ()
1018 return GNUNET_YES; 1098 return GNUNET_YES;
1019} 1099}
1020 1100
1101void handle_response(struct dns_pkt* dns, struct sockaddr *addr, socklen_t addrlen, int r);
1102
1103/**
1104 * Read a response-packet of the UDP-Socket
1105 */
1106static void
1107read_response6 (void *cls
1108 __attribute__ ((unused)),
1109 const struct GNUNET_SCHEDULER_TaskContext *tc)
1110{
1111 struct sockaddr_in6 addr;
1112 socklen_t addrlen = sizeof (addr);
1113 int r;
1114 int len;
1115
1116 if (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)
1117 return;
1118
1119 memset (&addr, 0, sizeof addr);
1120
1121#ifndef MINGW
1122 if (0 != ioctl (GNUNET_NETWORK_get_fd (dnsout6), FIONREAD, &len))
1123 {
1124 (void)open_port6 ();
1125 return;
1126 }
1127#else
1128 /* port the code above? */
1129 len = 65536;
1130#endif
1131
1132 unsigned char buf[len];
1133 struct dns_pkt *dns = (struct dns_pkt *) buf;
1134
1135 r = GNUNET_NETWORK_socket_recvfrom (dnsout, buf, sizeof (buf),
1136 (struct sockaddr *) &addr, &addrlen);
1137
1138 if (r < 0)
1139 {
1140 (void)open_port6 ();
1141 return;
1142 }
1143
1144 struct sockaddr *addr_ = GNUNET_malloc(sizeof addr);
1145 memcpy (addr_, &addr, sizeof addr);
1146 handle_response(dns, addr_, 4, r);
1147
1148 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, dnsout6,
1149 &read_response6, NULL);
1150}
1151
1021/** 1152/**
1022 * Read a response-packet of the UDP-Socket 1153 * Read a response-packet of the UDP-Socket
1023 */ 1154 */
@@ -1050,14 +1181,14 @@ read_response (void *cls
1050 /* port the code above? */ 1181 /* port the code above? */
1051 len = 65536; 1182 len = 65536;
1052#endif 1183#endif
1053 {
1054 unsigned char buf[len];
1055 struct dns_pkt *dns = (struct dns_pkt *) buf;
1056 1184
1057 r = GNUNET_NETWORK_socket_recvfrom (dnsout, buf, sizeof (buf), 1185 unsigned char buf[len];
1058 (struct sockaddr *) &addr, &addrlen); 1186 struct dns_pkt *dns = (struct dns_pkt *) buf;
1059 1187
1060 if (r < 0) 1188 r = GNUNET_NETWORK_socket_recvfrom (dnsout, buf, sizeof (buf),
1189 (struct sockaddr *) &addr, &addrlen);
1190
1191 if (r < 0)
1061 { 1192 {
1062 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, 1193 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
1063 "recvfrom"); 1194 "recvfrom");
@@ -1067,86 +1198,112 @@ read_response (void *cls
1067 return; 1198 return;
1068 } 1199 }
1069 1200
1070 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Answer to query %d\n", 1201 struct sockaddr *addr_ = GNUNET_malloc(sizeof addr);
1071 ntohs (dns->s.id)); 1202 memcpy (addr_, &addr, sizeof addr);
1203 handle_response(dns, addr_, 4, r);
1204
1205 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, dnsout,
1206 &read_response, NULL);
1207}
1208
1209void
1210handle_response(struct dns_pkt* dns, struct sockaddr *addr, socklen_t addrlen, int r)
1211{
1212 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Answer to query %d\n",
1213 ntohs (dns->s.id));
1214
1072 1215
1073 if (query_states[dns->s.id].valid == GNUNET_YES) 1216 if (query_states[dns->s.id].valid == GNUNET_YES)
1074 { 1217 {
1075 if (query_states[dns->s.id].tunnel != NULL) 1218 if (query_states[dns->s.id].tunnel != NULL)
1076 {
1077 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1078 "Answer to query %d for a remote peer!\n",
1079 ntohs (dns->s.id));
1080 /* This response should go through a tunnel */
1081 uint32_t *c =
1082 GNUNET_malloc (4 + sizeof (struct GNUNET_MESH_Tunnel *) + r);
1083 *c = r;
1084 struct GNUNET_MESH_Tunnel **t = (struct GNUNET_MESH_Tunnel **) (c + 1);
1085
1086 *t = query_states[dns->s.id].tunnel;
1087 memcpy (t + 1, dns, r);
1088 if (NULL ==
1089 GNUNET_MESH_tunnel_get_data (query_states[dns->s.id].tunnel))
1090 { 1219 {
1091 struct GNUNET_MESH_TransmitHandle *th = 1220 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1092 GNUNET_MESH_notify_transmit_ready (query_states[dns->s.id].tunnel, 1221 "Answer to query %d for a remote peer!\n",
1093 GNUNET_YES, 1222 ntohs (dns->s.id));
1094 32, 1223 /* This response should go through a tunnel */
1095 GNUNET_TIME_UNIT_MINUTES, 1224 uint32_t *c =
1096 NULL, 1225 GNUNET_malloc (4 + sizeof (struct GNUNET_MESH_Tunnel *) + r);
1097 r + 1226 *c = r;
1098 sizeof (struct 1227 struct GNUNET_MESH_Tunnel **t = (struct GNUNET_MESH_Tunnel **) (c + 1);
1099 GNUNET_MessageHeader), 1228
1100 mesh_send_response, c); 1229 *t = query_states[dns->s.id].tunnel;
1101 1230 memcpy (t + 1, dns, r);
1102 GNUNET_MESH_tunnel_set_data (query_states[dns->s.id].tunnel, th); 1231 if (NULL ==
1103 } 1232 GNUNET_MESH_tunnel_get_data (query_states[dns->s.id].tunnel))
1104 else 1233 {
1105 { 1234 struct GNUNET_MESH_TransmitHandle *th =
1106 struct tunnel_notify_queue *head = 1235 GNUNET_MESH_notify_transmit_ready (query_states[dns->s.id].tunnel,
1107 GNUNET_MESH_tunnel_get_head (query_states[dns->s.id].tunnel); 1236 GNUNET_YES,
1108 struct tunnel_notify_queue *tail = 1237 32,
1109 GNUNET_MESH_tunnel_get_tail (query_states[dns->s.id].tunnel); 1238 GNUNET_TIME_UNIT_MINUTES,
1110 1239 NULL,
1111 struct tunnel_notify_queue *element = 1240 r +
1112 GNUNET_malloc (sizeof (struct tunnel_notify_queue)); 1241 sizeof (struct
1113 element->cls = c; 1242 GNUNET_MessageHeader),
1114 element->len = r + sizeof (struct GNUNET_MessageHeader); 1243 mesh_send_response, c);
1115 element->cb = mesh_send_response; 1244
1116 1245 GNUNET_MESH_tunnel_set_data (query_states[dns->s.id].tunnel, th);
1117 GNUNET_CONTAINER_DLL_insert_tail (head, tail, element); 1246 }
1118 GNUNET_MESH_tunnel_set_head (query_states[dns->s.id].tunnel, head); 1247 else
1119 GNUNET_MESH_tunnel_set_tail (query_states[dns->s.id].tunnel, tail); 1248 {
1249 struct tunnel_notify_queue *head =
1250 GNUNET_MESH_tunnel_get_head (query_states[dns->s.id].tunnel);
1251 struct tunnel_notify_queue *tail =
1252 GNUNET_MESH_tunnel_get_tail (query_states[dns->s.id].tunnel);
1253
1254 struct tunnel_notify_queue *element =
1255 GNUNET_malloc (sizeof (struct tunnel_notify_queue));
1256 element->cls = c;
1257 element->len = r + sizeof (struct GNUNET_MessageHeader);
1258 element->cb = mesh_send_response;
1259
1260 GNUNET_CONTAINER_DLL_insert_tail (head, tail, element);
1261 GNUNET_MESH_tunnel_set_head (query_states[dns->s.id].tunnel, head);
1262 GNUNET_MESH_tunnel_set_tail (query_states[dns->s.id].tunnel, tail);
1263 }
1120 } 1264 }
1121 }
1122 else 1265 else
1123 { 1266 {
1124 query_states[dns->s.id].valid = GNUNET_NO; 1267 query_states[dns->s.id].valid = GNUNET_NO;
1125 1268
1126 size_t len = sizeof (struct answer_packet) + r - 1; /* 1 for the unsigned char data[1]; */ 1269 size_t len = sizeof (struct answer_packet) + r - 1; /* 1 for the unsigned char data[1]; */
1127 struct answer_packet_list *answer = 1270 struct answer_packet_list *answer =
1128 GNUNET_malloc (len + 2 * sizeof (struct answer_packet_list *)); 1271 GNUNET_malloc (len + 2 * sizeof (struct answer_packet_list *));
1129 answer->pkt.hdr.type = 1272 answer->pkt.hdr.type =
1130 htons (GNUNET_MESSAGE_TYPE_VPN_DNS_LOCAL_RESPONSE_DNS); 1273 htons (GNUNET_MESSAGE_TYPE_VPN_DNS_LOCAL_RESPONSE_DNS);
1131 answer->pkt.hdr.size = htons (len); 1274 answer->pkt.hdr.size = htons (len);
1132 answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_IP; 1275 answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_IP;
1133 answer->pkt.from = addr.sin_addr.s_addr; 1276 answer->pkt.addrlen = addrlen;
1134 answer->pkt.to = query_states[dns->s.id].local_ip; 1277 if (addrlen == 16)
1135 answer->pkt.dst_port = query_states[dns->s.id].local_port; 1278 {
1136 memcpy (answer->pkt.data, buf, r); 1279 struct sockaddr_in6 *addr_ = (struct sockaddr_in6*)addr;
1137 1280 memcpy(answer->pkt.from, &addr_->sin6_addr, addrlen);
1138 GNUNET_CONTAINER_DLL_insert_after (head, tail, tail, answer); 1281 memcpy(answer->pkt.to, query_states[dns->s.id].local_ip, addrlen);
1139 1282 }
1140 if (server_notify == NULL) 1283 else if (addrlen == 4)
1141 server_notify = GNUNET_SERVER_notify_transmit_ready (query_states[dns->s.id].client, 1284 {
1142 len, GNUNET_TIME_UNIT_FOREVER_REL, 1285 struct sockaddr_in *addr_ = (struct sockaddr_in*)addr;
1143 &send_answer, 1286 memcpy(answer->pkt.from, &addr_->sin_addr.s_addr, addrlen);
1144 query_states[dns->s.id].client); 1287 memcpy(answer->pkt.to, query_states[dns->s.id].local_ip, addrlen);
1145 } 1288 }
1289 else
1290 {
1291 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "addrlen = %d\n", addrlen);
1292 GNUNET_assert(0);
1293 }
1294 answer->pkt.dst_port = query_states[dns->s.id].local_port;
1295 memcpy (answer->pkt.data, dns, r);
1296
1297 GNUNET_CONTAINER_DLL_insert_after (head, tail, tail, answer);
1298
1299 if (server_notify == NULL)
1300 server_notify = GNUNET_SERVER_notify_transmit_ready (query_states[dns->s.id].client,
1301 len, GNUNET_TIME_UNIT_FOREVER_REL,
1302 &send_answer,
1303 query_states[dns->s.id].client);
1304 }
1146 } 1305 }
1147 } 1306 GNUNET_free(addr);
1148 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, dnsout,
1149 &read_response, NULL);
1150} 1307}
1151 1308
1152 1309
@@ -1422,6 +1579,11 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
1422 GNUNET_APPLICATION_TYPE_END 1579 GNUNET_APPLICATION_TYPE_END
1423 }; 1580 };
1424 1581
1582 if (GNUNET_YES != open_port6 ())
1583 {
1584 GNUNET_SCHEDULER_shutdown ();
1585 return;
1586 }
1425 1587
1426 if (GNUNET_YES != open_port ()) 1588 if (GNUNET_YES != open_port ())
1427 { 1589 {