diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gns/gns_api.c | 7 | ||||
-rw-r--r-- | src/gns/gnunet-gns.c | 10 | ||||
-rw-r--r-- | src/gns/nss/nss_gns.c | 269 | ||||
-rw-r--r-- | src/gns/nss/nss_gns_query.c | 25 | ||||
-rw-r--r-- | src/gns/nss/nss_gns_query.h | 30 | ||||
-rw-r--r-- | src/identity/identity_api_lookup.c | 8 | ||||
-rw-r--r-- | src/util/Makefile.am | 16 | ||||
-rw-r--r-- | src/util/client.c | 13 | ||||
-rw-r--r-- | src/util/gnunet-timeout-w32.c | 191 | ||||
-rw-r--r-- | src/util/gnunet-timeout.c | 128 |
10 files changed, 532 insertions, 165 deletions
diff --git a/src/gns/gns_api.c b/src/gns/gns_api.c index 0ec9209da..3b658da92 100644 --- a/src/gns/gns_api.c +++ b/src/gns/gns_api.c | |||
@@ -11,7 +11,7 @@ | |||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Affero General Public License for more details. | 13 | Affero General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU Affero General Public License | 15 | You should have received a copy of the GNU Affero General Public License |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | */ | 17 | */ |
@@ -232,7 +232,6 @@ reconnect (struct GNUNET_GNS_Handle *handle) | |||
232 | handle), | 232 | handle), |
233 | GNUNET_MQ_handler_end () | 233 | GNUNET_MQ_handler_end () |
234 | }; | 234 | }; |
235 | struct GNUNET_GNS_LookupRequest *lh; | ||
236 | 235 | ||
237 | GNUNET_assert (NULL == handle->mq); | 236 | GNUNET_assert (NULL == handle->mq); |
238 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 237 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
@@ -244,7 +243,9 @@ reconnect (struct GNUNET_GNS_Handle *handle) | |||
244 | handle); | 243 | handle); |
245 | if (NULL == handle->mq) | 244 | if (NULL == handle->mq) |
246 | return; | 245 | return; |
247 | for (lh = handle->lookup_head; NULL != lh; lh = lh->next) | 246 | for (struct GNUNET_GNS_LookupRequest *lh = handle->lookup_head; |
247 | NULL != lh; | ||
248 | lh = lh->next) | ||
248 | GNUNET_MQ_send_copy (handle->mq, | 249 | GNUNET_MQ_send_copy (handle->mq, |
249 | lh->env); | 250 | lh->env); |
250 | } | 251 | } |
diff --git a/src/gns/gnunet-gns.c b/src/gns/gnunet-gns.c index 149c8a7bb..463348ed3 100644 --- a/src/gns/gnunet-gns.c +++ b/src/gns/gnunet-gns.c | |||
@@ -11,7 +11,7 @@ | |||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Affero General Public License for more details. | 13 | Affero General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU Affero General Public License | 15 | You should have received a copy of the GNU Affero General Public License |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | */ | 17 | */ |
@@ -65,8 +65,9 @@ static struct GNUNET_GNS_LookupWithTldRequest *lr; | |||
65 | /** | 65 | /** |
66 | * Global return value. | 66 | * Global return value. |
67 | * 0 on success (default), | 67 | * 0 on success (default), |
68 | * 1 on internal failures, 2 on launch failure, | 68 | * 1 on internal failures |
69 | * 3 if the name is not a GNS-supported TLD, | 69 | * 2 on launch failure, |
70 | * 4 if the name is not a GNS-supported TLD, | ||
70 | */ | 71 | */ |
71 | static int global_ret; | 72 | static int global_ret; |
72 | 73 | ||
@@ -114,7 +115,7 @@ process_lookup_result (void *cls, | |||
114 | lr = NULL; | 115 | lr = NULL; |
115 | if (GNUNET_NO == was_gns) | 116 | if (GNUNET_NO == was_gns) |
116 | { | 117 | { |
117 | global_ret = 3; | 118 | global_ret = 4; /* not for GNS */ |
118 | GNUNET_SCHEDULER_shutdown (); | 119 | GNUNET_SCHEDULER_shutdown (); |
119 | return; | 120 | return; |
120 | } | 121 | } |
@@ -183,7 +184,6 @@ run (void *cls, | |||
183 | global_ret = 2; | 184 | global_ret = 2; |
184 | return; | 185 | return; |
185 | } | 186 | } |
186 | |||
187 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, | 187 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, |
188 | NULL); | 188 | NULL); |
189 | 189 | ||
diff --git a/src/gns/nss/nss_gns.c b/src/gns/nss/nss_gns.c index 9c9233d35..58aab47fd 100644 --- a/src/gns/nss/nss_gns.c +++ b/src/gns/nss/nss_gns.c | |||
@@ -54,121 +54,126 @@ | |||
54 | * @return a nss_status code | 54 | * @return a nss_status code |
55 | */ | 55 | */ |
56 | enum nss_status | 56 | enum nss_status |
57 | _nss_gns_gethostbyname2_r( | 57 | _nss_gns_gethostbyname2_r(const char *name, |
58 | const char *name, | 58 | int af, |
59 | int af, | 59 | struct hostent *result, |
60 | struct hostent * result, | 60 | char *buffer, |
61 | char *buffer, | 61 | size_t buflen, |
62 | size_t buflen, | 62 | int *errnop, |
63 | int *errnop, | 63 | int *h_errnop) |
64 | int *h_errnop) { | 64 | { |
65 | 65 | struct userdata u; | |
66 | struct userdata u; | 66 | enum nss_status status = NSS_STATUS_UNAVAIL; |
67 | enum nss_status status = NSS_STATUS_UNAVAIL; | 67 | int i; |
68 | int i; | 68 | size_t address_length; |
69 | size_t address_length, l, idx, astart; | 69 | size_t l; |
70 | 70 | size_t idx; | |
71 | if (af == AF_UNSPEC) | 71 | size_t astart; |
72 | |||
73 | if (af == AF_UNSPEC) | ||
72 | #ifdef NSS_IPV6_ONLY | 74 | #ifdef NSS_IPV6_ONLY |
73 | af = AF_INET6; | 75 | af = AF_INET6; |
74 | #else | 76 | #else |
75 | af = AF_INET; | 77 | af = AF_INET; |
76 | #endif | 78 | #endif |
77 | 79 | ||
78 | #ifdef NSS_IPV4_ONLY | 80 | #ifdef NSS_IPV4_ONLY |
79 | if (af != AF_INET) | 81 | if (af != AF_INET) |
80 | #elif NSS_IPV6_ONLY | 82 | #elif NSS_IPV6_ONLY |
81 | if (af != AF_INET6) | 83 | if (af != AF_INET6) |
82 | #else | 84 | #else |
83 | if (af != AF_INET && af != AF_INET6) | 85 | if ( (af != AF_INET) && |
86 | (af != AF_INET6) ) | ||
84 | #endif | 87 | #endif |
85 | { | 88 | { |
86 | *errnop = EINVAL; | 89 | *errnop = EINVAL; |
87 | *h_errnop = NO_RECOVERY; | 90 | *h_errnop = NO_RECOVERY; |
88 | 91 | ||
89 | goto finish; | 92 | goto finish; |
90 | } | 93 | } |
91 | |||
92 | address_length = af == AF_INET ? sizeof(ipv4_address_t) : sizeof(ipv6_address_t); | ||
93 | if (buflen < | ||
94 | sizeof(char*)+ /* alias names */ | ||
95 | strlen(name)+1) { /* official name */ | ||
96 | |||
97 | *errnop = ERANGE; | ||
98 | *h_errnop = NO_RECOVERY; | ||
99 | status = NSS_STATUS_TRYAGAIN; | ||
100 | |||
101 | goto finish; | ||
102 | } | ||
103 | |||
104 | u.count = 0; | ||
105 | u.data_len = 0; | ||
106 | |||
107 | i = gns_resolve_name(af, name, &u); | ||
108 | if (-3 == i) | ||
109 | { | ||
110 | status = NSS_STATUS_NOTFOUND; | ||
111 | goto finish; | ||
112 | } | ||
113 | if (-2 == i) | ||
114 | { | ||
115 | status = NSS_STATUS_UNAVAIL; | ||
116 | goto finish; | ||
117 | } | ||
118 | if ( (-1 == i) || | ||
119 | (u.count == 0) ) | ||
120 | { | ||
121 | *errnop = ETIMEDOUT; | ||
122 | *h_errnop = HOST_NOT_FOUND; | ||
123 | status = NSS_STATUS_NOTFOUND; | ||
124 | goto finish; | ||
125 | } | ||
126 | |||
127 | |||
128 | /* Alias names */ | ||
129 | *((char**) buffer) = NULL; | ||
130 | result->h_aliases = (char**) buffer; | ||
131 | idx = sizeof(char*); | ||
132 | |||
133 | /* Official name */ | ||
134 | strcpy(buffer+idx, name); | ||
135 | result->h_name = buffer+idx; | ||
136 | idx += strlen(name)+1; | ||
137 | |||
138 | ALIGN(idx); | ||
139 | |||
140 | result->h_addrtype = af; | ||
141 | result->h_length = address_length; | ||
142 | |||
143 | /* Check if there's enough space for the addresses */ | ||
144 | if (buflen < idx+u.data_len+sizeof(char*)*(u.count+1)) { | ||
145 | *errnop = ERANGE; | ||
146 | *h_errnop = NO_RECOVERY; | ||
147 | status = NSS_STATUS_TRYAGAIN; | ||
148 | goto finish; | ||
149 | } | ||
150 | 94 | ||
95 | address_length = (af == AF_INET) ? sizeof(ipv4_address_t) : sizeof(ipv6_address_t); | ||
96 | if (buflen < | ||
97 | sizeof(char*)+ /* alias names */ | ||
98 | strlen(name)+1) | ||
99 | { /* official name */ | ||
100 | *errnop = ERANGE; | ||
101 | *h_errnop = NO_RECOVERY; | ||
102 | status = NSS_STATUS_TRYAGAIN; | ||
103 | |||
104 | goto finish; | ||
105 | } | ||
106 | u.count = 0; | ||
107 | u.data_len = 0; | ||
108 | i = gns_resolve_name (af, | ||
109 | name, | ||
110 | &u); | ||
111 | if (-3 == i) | ||
112 | { | ||
113 | status = NSS_STATUS_NOTFOUND; | ||
114 | goto finish; | ||
115 | } | ||
116 | if (-2 == i) | ||
117 | { | ||
118 | status = NSS_STATUS_UNAVAIL; | ||
119 | goto finish; | ||
120 | } | ||
121 | if ( (-1 == i) || | ||
122 | (u.count == 0) ) | ||
123 | { | ||
124 | *errnop = ETIMEDOUT; | ||
125 | *h_errnop = HOST_NOT_FOUND; | ||
126 | status = NSS_STATUS_NOTFOUND; | ||
127 | goto finish; | ||
128 | } | ||
129 | /* Alias names */ | ||
130 | *((char**) buffer) = NULL; | ||
131 | result->h_aliases = (char**) buffer; | ||
132 | idx = sizeof(char*); | ||
133 | |||
134 | /* Official name */ | ||
135 | strcpy (buffer+idx, | ||
136 | name); | ||
137 | result->h_name = buffer+idx; | ||
138 | idx += strlen (name)+1; | ||
139 | |||
140 | ALIGN(idx); | ||
141 | |||
142 | result->h_addrtype = af; | ||
143 | result->h_length = address_length; | ||
144 | |||
145 | /* Check if there's enough space for the addresses */ | ||
146 | if (buflen < idx+u.data_len+sizeof(char*)*(u.count+1)) | ||
147 | { | ||
148 | *errnop = ERANGE; | ||
149 | *h_errnop = NO_RECOVERY; | ||
150 | status = NSS_STATUS_TRYAGAIN; | ||
151 | goto finish; | ||
152 | } | ||
151 | /* Addresses */ | 153 | /* Addresses */ |
152 | astart = idx; | 154 | astart = idx; |
153 | l = u.count*address_length; | 155 | l = u.count*address_length; |
154 | if (0 != l) | 156 | if (0 != l) |
155 | memcpy(buffer+astart, &u.data, l); | 157 | memcpy (buffer+astart, |
156 | /* address_length is a multiple of 32bits, so idx is still aligned | 158 | &u.data, |
157 | * correctly */ | 159 | l); |
158 | idx += l; | 160 | /* address_length is a multiple of 32bits, so idx is still aligned |
159 | 161 | * correctly */ | |
160 | /* Address array address_length is always a multiple of 32bits */ | 162 | idx += l; |
161 | for (i = 0; i < u.count; i++) | 163 | |
162 | ((char**) (buffer+idx))[i] = buffer+astart+address_length*i; | 164 | /* Address array address_length is always a multiple of 32bits */ |
163 | ((char**) (buffer+idx))[i] = NULL; | 165 | for (i = 0; i < u.count; i++) |
164 | result->h_addr_list = (char**) (buffer+idx); | 166 | ((char**) (buffer+idx))[i] = buffer+astart+address_length*i; |
165 | 167 | ((char**) (buffer+idx))[i] = NULL; | |
166 | status = NSS_STATUS_SUCCESS; | 168 | result->h_addr_list = (char**) (buffer+idx); |
169 | |||
170 | status = NSS_STATUS_SUCCESS; | ||
167 | 171 | ||
168 | finish: | 172 | finish: |
169 | return status; | 173 | return status; |
170 | } | 174 | } |
171 | 175 | ||
176 | |||
172 | /** | 177 | /** |
173 | * The gethostbyname hook executed by nsswitch | 178 | * The gethostbyname hook executed by nsswitch |
174 | * | 179 | * |
@@ -176,29 +181,28 @@ finish: | |||
176 | * @param result the result hostent | 181 | * @param result the result hostent |
177 | * @param buffer the result buffer | 182 | * @param buffer the result buffer |
178 | * @param buflen length of the buffer | 183 | * @param buflen length of the buffer |
179 | * @param errnop idk | 184 | * @param errnop[out] the low-level error code to return to the application |
180 | * @param h_errnop idk | 185 | * @param h_errnop idk |
181 | * @return a nss_status code | 186 | * @return a nss_status code |
182 | */ | 187 | */ |
183 | enum nss_status | 188 | enum nss_status |
184 | _nss_gns_gethostbyname_r ( | 189 | _nss_gns_gethostbyname_r (const char *name, |
185 | const char *name, | 190 | struct hostent *result, |
186 | struct hostent *result, | 191 | char *buffer, |
187 | char *buffer, | 192 | size_t buflen, |
188 | size_t buflen, | 193 | int *errnop, |
189 | int *errnop, | 194 | int *h_errnop) |
190 | int *h_errnop) { | 195 | { |
191 | 196 | return _nss_gns_gethostbyname2_r (name, | |
192 | return _nss_gns_gethostbyname2_r( | 197 | AF_UNSPEC, |
193 | name, | 198 | result, |
194 | AF_UNSPEC, | 199 | buffer, |
195 | result, | 200 | buflen, |
196 | buffer, | 201 | errnop, |
197 | buflen, | 202 | h_errnop); |
198 | errnop, | ||
199 | h_errnop); | ||
200 | } | 203 | } |
201 | 204 | ||
205 | |||
202 | /** | 206 | /** |
203 | * The gethostbyaddr hook executed by nsswitch | 207 | * The gethostbyaddr hook executed by nsswitch |
204 | * We can't do this so we always return NSS_STATUS_UNAVAIL | 208 | * We can't do this so we always return NSS_STATUS_UNAVAIL |
@@ -209,23 +213,22 @@ _nss_gns_gethostbyname_r ( | |||
209 | * @param result the result hostent | 213 | * @param result the result hostent |
210 | * @param buffer the result buffer | 214 | * @param buffer the result buffer |
211 | * @param buflen length of the buffer | 215 | * @param buflen length of the buffer |
212 | * @param errnop idk | 216 | * @param errnop[out] the low-level error code to return to the application |
213 | * @param h_errnop idk | 217 | * @param h_errnop idk |
214 | * @return NSS_STATUS_UNAVAIL | 218 | * @return NSS_STATUS_UNAVAIL |
215 | */ | 219 | */ |
216 | enum nss_status | 220 | enum nss_status |
217 | _nss_gns_gethostbyaddr_r( | 221 | _nss_gns_gethostbyaddr_r (const void* addr, |
218 | const void* addr, | 222 | int len, |
219 | int len, | 223 | int af, |
220 | int af, | 224 | struct hostent *result, |
221 | struct hostent *result, | 225 | char *buffer, |
222 | char *buffer, | 226 | size_t buflen, |
223 | size_t buflen, | 227 | int *errnop, |
224 | int *errnop, | 228 | int *h_errnop) |
225 | int *h_errnop) { | 229 | { |
226 | 230 | *errnop = EINVAL; | |
227 | *errnop = EINVAL; | 231 | *h_errnop = NO_RECOVERY; |
228 | *h_errnop = NO_RECOVERY; | 232 | //NOTE we allow to leak this into DNS so no NOTFOUND |
229 | //NOTE we allow to leak this into DNS so no NOTFOUND | 233 | return NSS_STATUS_UNAVAIL; |
230 | return NSS_STATUS_UNAVAIL; | ||
231 | } | 234 | } |
diff --git a/src/gns/nss/nss_gns_query.c b/src/gns/nss/nss_gns_query.c index 094e25ed5..867ead624 100644 --- a/src/gns/nss/nss_gns_query.c +++ b/src/gns/nss/nss_gns_query.c | |||
@@ -11,7 +11,7 @@ | |||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Affero General Public License for more details. | 13 | Affero General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU Affero General Public License | 15 | You should have received a copy of the GNU Affero General Public License |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | */ | 17 | */ |
@@ -48,14 +48,16 @@ gns_resolve_name (int af, | |||
48 | { | 48 | { |
49 | if (-1 == asprintf (&cmd, | 49 | if (-1 == asprintf (&cmd, |
50 | "%s -t AAAA -u %s\n", | 50 | "%s -t AAAA -u %s\n", |
51 | "gnunet-gns -r", name)) | 51 | "gnunet-gns -r", |
52 | name)) | ||
52 | return -1; | 53 | return -1; |
53 | } | 54 | } |
54 | else | 55 | else |
55 | { | 56 | { |
56 | if (-1 == asprintf (&cmd, | 57 | if (-1 == asprintf (&cmd, |
57 | "%s %s\n", | 58 | "%s %s\n", |
58 | "gnunet-gns -r -u", name)) | 59 | "gnunet-gns -r -u", |
60 | name)) | ||
59 | return -1; | 61 | return -1; |
60 | } | 62 | } |
61 | if (NULL == (p = popen (cmd, "r"))) | 63 | if (NULL == (p = popen (cmd, "r"))) |
@@ -63,7 +65,9 @@ gns_resolve_name (int af, | |||
63 | free (cmd); | 65 | free (cmd); |
64 | return -1; | 66 | return -1; |
65 | } | 67 | } |
66 | while (NULL != fgets (line, sizeof(line), p)) | 68 | while (NULL != fgets (line, |
69 | sizeof(line), | ||
70 | p)) | ||
67 | { | 71 | { |
68 | if (u->count >= MAX_ENTRIES) | 72 | if (u->count >= MAX_ENTRIES) |
69 | break; | 73 | break; |
@@ -72,7 +76,9 @@ gns_resolve_name (int af, | |||
72 | line[strlen(line)-1] = '\0'; | 76 | line[strlen(line)-1] = '\0'; |
73 | if (AF_INET == af) | 77 | if (AF_INET == af) |
74 | { | 78 | { |
75 | if (inet_pton(af, line, &(u->data.ipv4[u->count]))) | 79 | if (inet_pton(af, |
80 | line, | ||
81 | &u->data.ipv4[u->count])) | ||
76 | { | 82 | { |
77 | u->count++; | 83 | u->count++; |
78 | u->data_len += sizeof(ipv4_address_t); | 84 | u->data_len += sizeof(ipv4_address_t); |
@@ -86,7 +92,9 @@ gns_resolve_name (int af, | |||
86 | } | 92 | } |
87 | else if (AF_INET6 == af) | 93 | else if (AF_INET6 == af) |
88 | { | 94 | { |
89 | if (inet_pton(af, line, &(u->data.ipv6[u->count]))) | 95 | if (inet_pton(af, |
96 | line, | ||
97 | &u->data.ipv6[u->count])) | ||
90 | { | 98 | { |
91 | u->count++; | 99 | u->count++; |
92 | u->data_len += sizeof(ipv6_address_t); | 100 | u->data_len += sizeof(ipv6_address_t); |
@@ -105,7 +113,10 @@ gns_resolve_name (int af, | |||
105 | if (4 == ret) | 113 | if (4 == ret) |
106 | return -2; /* not for GNS */ | 114 | return -2; /* not for GNS */ |
107 | if (3 == ret) | 115 | if (3 == ret) |
108 | return -3; /* timeout */ | 116 | return -3; /* timeout -> not found */ |
117 | if ( (2 == ret) || (1 == ret) ) | ||
118 | return -2; /* launch failure -> service unavailable */ | ||
109 | return 0; | 119 | return 0; |
110 | } | 120 | } |
121 | |||
111 | /* end of nss_gns_query.c */ | 122 | /* end of nss_gns_query.c */ |
diff --git a/src/gns/nss/nss_gns_query.h b/src/gns/nss/nss_gns_query.h index bb04f9004..48cab4b22 100644 --- a/src/gns/nss/nss_gns_query.h +++ b/src/gns/nss/nss_gns_query.h | |||
@@ -11,7 +11,7 @@ | |||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Affero General Public License for more details. | 13 | Affero General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU Affero General Public License | 15 | You should have received a copy of the GNU Affero General Public License |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | */ | 17 | */ |
@@ -26,25 +26,30 @@ | |||
26 | /* Maximum number of entries to return */ | 26 | /* Maximum number of entries to return */ |
27 | #define MAX_ENTRIES 16 | 27 | #define MAX_ENTRIES 16 |
28 | 28 | ||
29 | typedef struct { | 29 | typedef struct |
30 | uint32_t address; | 30 | { |
31 | uint32_t address; | ||
31 | } ipv4_address_t; | 32 | } ipv4_address_t; |
32 | 33 | ||
33 | typedef struct { | 34 | |
34 | uint8_t address[16]; | 35 | typedef struct |
36 | { | ||
37 | uint8_t address[16]; | ||
35 | } ipv6_address_t; | 38 | } ipv6_address_t; |
36 | 39 | ||
37 | 40 | ||
38 | struct userdata { | 41 | struct userdata |
42 | { | ||
39 | int count; | 43 | int count; |
40 | int data_len; /* only valid when doing reverse lookup */ | 44 | int data_len; /* only valid when doing reverse lookup */ |
41 | union { | 45 | union { |
42 | ipv4_address_t ipv4[MAX_ENTRIES]; | 46 | ipv4_address_t ipv4[MAX_ENTRIES]; |
43 | ipv6_address_t ipv6[MAX_ENTRIES]; | 47 | ipv6_address_t ipv6[MAX_ENTRIES]; |
44 | char *name[MAX_ENTRIES]; | 48 | char *name[MAX_ENTRIES]; |
45 | } data; | 49 | } data; |
46 | }; | 50 | }; |
47 | 51 | ||
52 | |||
48 | /** | 53 | /** |
49 | * Wrapper function that uses gnunet-gns cli tool to resolve | 54 | * Wrapper function that uses gnunet-gns cli tool to resolve |
50 | * an IPv4/6 address. | 55 | * an IPv4/6 address. |
@@ -54,8 +59,9 @@ struct userdata { | |||
54 | * @param u the userdata (result struct) | 59 | * @param u the userdata (result struct) |
55 | * @return -1 on error else 0 | 60 | * @return -1 on error else 0 |
56 | */ | 61 | */ |
57 | int gns_resolve_name(int af, | 62 | int |
58 | const char *name, | 63 | gns_resolve_name(int af, |
59 | struct userdata *userdata); | 64 | const char *name, |
65 | struct userdata *userdata); | ||
60 | 66 | ||
61 | #endif | 67 | #endif |
diff --git a/src/identity/identity_api_lookup.c b/src/identity/identity_api_lookup.c index 593a5dbb0..25aec8ede 100644 --- a/src/identity/identity_api_lookup.c +++ b/src/identity/identity_api_lookup.c | |||
@@ -11,7 +11,7 @@ | |||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Affero General Public License for more details. | 13 | Affero General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU Affero General Public License | 15 | You should have received a copy of the GNU Affero General Public License |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | */ | 17 | */ |
@@ -131,6 +131,12 @@ GNUNET_IDENTITY_ego_lookup (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
131 | el->identity = GNUNET_IDENTITY_connect (cfg, | 131 | el->identity = GNUNET_IDENTITY_connect (cfg, |
132 | &identity_cb, | 132 | &identity_cb, |
133 | el); | 133 | el); |
134 | if (NULL == el->identity) | ||
135 | { | ||
136 | GNUNET_free (el->name); | ||
137 | GNUNET_free (el); | ||
138 | return NULL; | ||
139 | } | ||
134 | return el; | 140 | return el; |
135 | } | 141 | } |
136 | 142 | ||
diff --git a/src/util/Makefile.am b/src/util/Makefile.am index ec7bcb016..4ae073c2c 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am | |||
@@ -166,6 +166,7 @@ lib_LTLIBRARIES = libgnunetutil.la | |||
166 | 166 | ||
167 | libexec_PROGRAMS = \ | 167 | libexec_PROGRAMS = \ |
168 | gnunet-service-resolver \ | 168 | gnunet-service-resolver \ |
169 | gnunet-timeout \ | ||
169 | $(W32CONSOLEHELPER) | 170 | $(W32CONSOLEHELPER) |
170 | 171 | ||
171 | bin_SCRIPTS =\ | 172 | bin_SCRIPTS =\ |
@@ -192,6 +193,15 @@ endif | |||
192 | endif | 193 | endif |
193 | 194 | ||
194 | 195 | ||
196 | if !MINGW | ||
197 | gnunet_timeout_SOURCES = \ | ||
198 | gnunet-timeout.c | ||
199 | else | ||
200 | gnunet_timeout_SOURCES = \ | ||
201 | gnunet-timeout-w32.c | ||
202 | endif | ||
203 | |||
204 | |||
195 | do_subst = $(SED) -e 's,[@]PYTHON[@],$(PYTHON),g' | 205 | do_subst = $(SED) -e 's,[@]PYTHON[@],$(PYTHON),g' |
196 | 206 | ||
197 | gnunet-qr: gnunet-qr.py.in Makefile | 207 | gnunet-qr: gnunet-qr.py.in Makefile |
@@ -334,12 +344,12 @@ test_hexcoder_LDADD = \ | |||
334 | test_tun_SOURCES = \ | 344 | test_tun_SOURCES = \ |
335 | test_tun.c | 345 | test_tun.c |
336 | test_tun_LDADD = \ | 346 | test_tun_LDADD = \ |
337 | libgnunetutil.la | 347 | libgnunetutil.la |
338 | 348 | ||
339 | test_regex_SOURCES = \ | 349 | test_regex_SOURCES = \ |
340 | test_regex.c | 350 | test_regex.c |
341 | test_regex_LDADD = \ | 351 | test_regex_LDADD = \ |
342 | libgnunetutil.la | 352 | libgnunetutil.la |
343 | 353 | ||
344 | test_os_start_process_SOURCES = \ | 354 | test_os_start_process_SOURCES = \ |
345 | test_os_start_process.c | 355 | test_os_start_process.c |
@@ -622,4 +632,4 @@ EXTRA_DIST = \ | |||
622 | test_resolver_api_data.conf \ | 632 | test_resolver_api_data.conf \ |
623 | test_service_data.conf \ | 633 | test_service_data.conf \ |
624 | test_speedup_data.conf \ | 634 | test_speedup_data.conf \ |
625 | gnunet-qr.py.in | 635 | gnunet-qr.py.in |
diff --git a/src/util/client.c b/src/util/client.c index 44e326eab..1f569255a 100644 --- a/src/util/client.c +++ b/src/util/client.c | |||
@@ -11,7 +11,7 @@ | |||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Affero General Public License for more details. | 13 | Affero General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU Affero General Public License | 15 | You should have received a copy of the GNU Affero General Public License |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | */ | 17 | */ |
@@ -721,6 +721,17 @@ test_service_configuration (const char *service_name, | |||
721 | &unixpath)) && | 721 | &unixpath)) && |
722 | (0 < strlen (unixpath))) | 722 | (0 < strlen (unixpath))) |
723 | ret = GNUNET_OK; | 723 | ret = GNUNET_OK; |
724 | else if ((GNUNET_OK == | ||
725 | GNUNET_CONFIGURATION_have_value (cfg, | ||
726 | service_name, | ||
727 | "UNIXPATH"))) | ||
728 | { | ||
729 | GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, | ||
730 | service_name, | ||
731 | "UNIXPATH", | ||
732 | _("not a valid filename")); | ||
733 | return GNUNET_SYSERR; /* UNIXPATH specified but invalid! */ | ||
734 | } | ||
724 | GNUNET_free_non_null (unixpath); | 735 | GNUNET_free_non_null (unixpath); |
725 | #endif | 736 | #endif |
726 | 737 | ||
diff --git a/src/util/gnunet-timeout-w32.c b/src/util/gnunet-timeout-w32.c new file mode 100644 index 000000000..78b268fe2 --- /dev/null +++ b/src/util/gnunet-timeout-w32.c | |||
@@ -0,0 +1,191 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2010 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, or | ||
8 | (at your 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 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | /** | ||
20 | * @file src/util/gnunet-timeout-w32.c | ||
21 | * @brief small tool starting a child process, waiting that it terminates or killing it after a given timeout period | ||
22 | * @author LRN | ||
23 | */ | ||
24 | |||
25 | #include <windows.h> | ||
26 | #include <sys/types.h> | ||
27 | #include <stdio.h> | ||
28 | |||
29 | int | ||
30 | main (int argc, char *argv[]) | ||
31 | { | ||
32 | int i; | ||
33 | DWORD wait_result; | ||
34 | wchar_t *commandline; | ||
35 | wchar_t **wargv; | ||
36 | wchar_t *arg; | ||
37 | unsigned int cmdlen; | ||
38 | STARTUPINFOW start; | ||
39 | PROCESS_INFORMATION proc; | ||
40 | |||
41 | wchar_t wpath[MAX_PATH + 1]; | ||
42 | |||
43 | wchar_t *pathbuf; | ||
44 | DWORD pathbuf_len, alloc_len; | ||
45 | wchar_t *ptr; | ||
46 | wchar_t *non_const_filename; | ||
47 | wchar_t *wcmd; | ||
48 | int wargc; | ||
49 | int timeout = 0; | ||
50 | ssize_t wrote; | ||
51 | |||
52 | HANDLE job; | ||
53 | |||
54 | if (argc < 3) | ||
55 | { | ||
56 | printf | ||
57 | ("arg 1: timeout in sec., arg 2: executable, arg<n> arguments\n"); | ||
58 | exit (1); | ||
59 | } | ||
60 | |||
61 | timeout = atoi (argv[1]); | ||
62 | |||
63 | if (timeout == 0) | ||
64 | timeout = 600; | ||
65 | |||
66 | commandline = GetCommandLineW (); | ||
67 | if (commandline == NULL) | ||
68 | { | ||
69 | printf ("Failed to get commandline: %lu\n", GetLastError ()); | ||
70 | exit (2); | ||
71 | } | ||
72 | |||
73 | wargv = CommandLineToArgvW (commandline, &wargc); | ||
74 | if (wargv == NULL || wargc <= 1) | ||
75 | { | ||
76 | printf ("Failed to get parse commandline: %lu\n", GetLastError ()); | ||
77 | exit (3); | ||
78 | } | ||
79 | |||
80 | job = CreateJobObject (NULL, NULL); | ||
81 | if (job == NULL) | ||
82 | { | ||
83 | printf ("Failed to create a job: %lu\n", GetLastError ()); | ||
84 | exit (4); | ||
85 | } | ||
86 | |||
87 | pathbuf_len = GetEnvironmentVariableW (L"PATH", (wchar_t *) &pathbuf, 0); | ||
88 | |||
89 | alloc_len = pathbuf_len + 1; | ||
90 | |||
91 | pathbuf = malloc (alloc_len * sizeof (wchar_t)); | ||
92 | |||
93 | ptr = pathbuf; | ||
94 | |||
95 | alloc_len = GetEnvironmentVariableW (L"PATH", ptr, pathbuf_len); | ||
96 | |||
97 | cmdlen = wcslen (wargv[2]); | ||
98 | if (cmdlen < 5 || wcscmp (&wargv[2][cmdlen - 4], L".exe") != 0) | ||
99 | { | ||
100 | non_const_filename = malloc (sizeof (wchar_t) * (cmdlen + 5)); | ||
101 | swprintf (non_const_filename, cmdlen + 5, L"%S.exe", wargv[2]); | ||
102 | } | ||
103 | else | ||
104 | { | ||
105 | non_const_filename = wcsdup (wargv[2]); | ||
106 | } | ||
107 | |||
108 | /* Check that this is the full path. If it isn't, search. */ | ||
109 | if (non_const_filename[1] == L':') | ||
110 | swprintf (wpath, sizeof (wpath) / sizeof (wchar_t), L"%S", non_const_filename); | ||
111 | else if (!SearchPathW | ||
112 | (pathbuf, non_const_filename, NULL, sizeof (wpath) / sizeof (wchar_t), | ||
113 | wpath, NULL)) | ||
114 | { | ||
115 | printf ("Failed to get find executable: %lu\n", GetLastError ()); | ||
116 | exit (5); | ||
117 | } | ||
118 | free (pathbuf); | ||
119 | free (non_const_filename); | ||
120 | |||
121 | cmdlen = wcslen (wpath) + 4; | ||
122 | i = 3; | ||
123 | while (NULL != (arg = wargv[i++])) | ||
124 | cmdlen += wcslen (arg) + 4; | ||
125 | |||
126 | wcmd = malloc (sizeof (wchar_t) * (cmdlen + 1)); | ||
127 | wrote = 0; | ||
128 | i = 2; | ||
129 | while (NULL != (arg = wargv[i++])) | ||
130 | { | ||
131 | /* This is to escape trailing slash */ | ||
132 | wchar_t arg_lastchar = arg[wcslen (arg) - 1]; | ||
133 | if (wrote == 0) | ||
134 | { | ||
135 | wrote += swprintf (&wcmd[wrote], cmdlen + 1 - wrote, L"\"%S%S\" ", wpath, | ||
136 | arg_lastchar == L'\\' ? L"\\" : L""); | ||
137 | } | ||
138 | else | ||
139 | { | ||
140 | if (wcschr (arg, L' ') != NULL) | ||
141 | wrote += swprintf (&wcmd[wrote], cmdlen + 1 - wrote, L"\"%S%S\"%S", arg, | ||
142 | arg_lastchar == L'\\' ? L"\\" : L"", i == wargc ? L"" : L" "); | ||
143 | else | ||
144 | wrote += swprintf (&wcmd[wrote], cmdlen + 1 - wrote, L"%S%S%S", arg, | ||
145 | arg_lastchar == L'\\' ? L"\\" : L"", i == wargc ? L"" : L" "); | ||
146 | } | ||
147 | } | ||
148 | |||
149 | LocalFree (wargv); | ||
150 | |||
151 | memset (&start, 0, sizeof (start)); | ||
152 | start.cb = sizeof (start); | ||
153 | |||
154 | if (!CreateProcessW (wpath, wcmd, NULL, NULL, TRUE, CREATE_SUSPENDED, | ||
155 | NULL, NULL, &start, &proc)) | ||
156 | { | ||
157 | wprintf (L"Failed to get spawn process `%S' with arguments `%S': %lu\n", wpath, wcmd, GetLastError ()); | ||
158 | exit (6); | ||
159 | } | ||
160 | |||
161 | AssignProcessToJobObject (job, proc.hProcess); | ||
162 | |||
163 | ResumeThread (proc.hThread); | ||
164 | CloseHandle (proc.hThread); | ||
165 | |||
166 | free (wcmd); | ||
167 | |||
168 | wait_result = WaitForSingleObject (proc.hProcess, timeout * 1000); | ||
169 | if (wait_result == WAIT_OBJECT_0) | ||
170 | { | ||
171 | DWORD status; | ||
172 | wait_result = GetExitCodeProcess (proc.hProcess, &status); | ||
173 | CloseHandle (proc.hProcess); | ||
174 | if (wait_result != 0) | ||
175 | { | ||
176 | printf ("Test process exited with result %lu\n", status); | ||
177 | TerminateJobObject (job, status); | ||
178 | exit (status); | ||
179 | } | ||
180 | printf ("Test process exited (failed to obtain exit status)\n"); | ||
181 | TerminateJobObject (job, 0); | ||
182 | exit (0); | ||
183 | } | ||
184 | printf ("Child processes were killed after timeout of %u seconds\n", | ||
185 | timeout); | ||
186 | TerminateJobObject (job, 1); | ||
187 | CloseHandle (proc.hProcess); | ||
188 | exit (1); | ||
189 | } | ||
190 | |||
191 | /* end of timeout_watchdog_w32.c */ | ||
diff --git a/src/util/gnunet-timeout.c b/src/util/gnunet-timeout.c new file mode 100644 index 000000000..8dfb6ad17 --- /dev/null +++ b/src/util/gnunet-timeout.c | |||
@@ -0,0 +1,128 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2010 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, or | ||
8 | (at your 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 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | /** | ||
20 | * @file src/util/gnunet-timeout.c | ||
21 | * @brief small tool starting a child process, waiting that it terminates or killing it after a given timeout period | ||
22 | * @author Matthias Wachs | ||
23 | */ | ||
24 | |||
25 | #include <sys/types.h> | ||
26 | #include <sys/wait.h> | ||
27 | #include <signal.h> | ||
28 | #include <stdio.h> | ||
29 | #include <stdlib.h> | ||
30 | #include <unistd.h> | ||
31 | |||
32 | static pid_t child; | ||
33 | |||
34 | |||
35 | static void | ||
36 | sigchld_handler (int val) | ||
37 | { | ||
38 | int status = 0; | ||
39 | int ret = 0; | ||
40 | |||
41 | (void) val; | ||
42 | waitpid (child, | ||
43 | &status, | ||
44 | 0); | ||
45 | if (WIFEXITED (status) != 0) | ||
46 | { | ||
47 | ret = WEXITSTATUS (status); | ||
48 | fprintf (stderr, | ||
49 | "Process exited with result %u\n", | ||
50 | ret); | ||
51 | exit (ret); /* return same status code */ | ||
52 | } | ||
53 | if (WIFSIGNALED (status) != 0) | ||
54 | { | ||
55 | ret = WTERMSIG (status); | ||
56 | fprintf (stderr, | ||
57 | "Process received signal %u\n", | ||
58 | ret); | ||
59 | kill (getpid (), | ||
60 | ret); /* kill self with the same signal */ | ||
61 | } | ||
62 | exit (-1); | ||
63 | } | ||
64 | |||
65 | |||
66 | static void | ||
67 | sigint_handler (int val) | ||
68 | { | ||
69 | kill (0, | ||
70 | val); | ||
71 | exit (val); | ||
72 | } | ||
73 | |||
74 | |||
75 | int | ||
76 | main (int argc, | ||
77 | char *argv[]) | ||
78 | { | ||
79 | int timeout = 0; | ||
80 | pid_t gpid = 0; | ||
81 | |||
82 | if (argc < 3) | ||
83 | { | ||
84 | fprintf (stderr, | ||
85 | "arg 1: timeout in sec., arg 2: executable, arg<n> arguments\n"); | ||
86 | exit (-1); | ||
87 | } | ||
88 | |||
89 | timeout = atoi (argv[1]); | ||
90 | |||
91 | if (timeout == 0) | ||
92 | timeout = 600; | ||
93 | |||
94 | /* with getpgid() it does not compile, but getpgrp is the BSD version and working */ | ||
95 | gpid = getpgrp (); | ||
96 | |||
97 | signal (SIGCHLD, sigchld_handler); | ||
98 | signal (SIGABRT, sigint_handler); | ||
99 | signal (SIGFPE, sigint_handler); | ||
100 | signal (SIGILL, sigint_handler); | ||
101 | signal (SIGINT, sigint_handler); | ||
102 | signal (SIGSEGV, sigint_handler); | ||
103 | signal (SIGTERM, sigint_handler); | ||
104 | |||
105 | child = fork (); | ||
106 | if (child == 0) | ||
107 | { | ||
108 | /* int setpgrp(pid_t pid, pid_t pgid); is not working on this machine */ | ||
109 | //setpgrp (0, pid_t gpid); | ||
110 | if (-1 != gpid) | ||
111 | setpgid (0, gpid); | ||
112 | execvp (argv[2], | ||
113 | &argv[2]); | ||
114 | exit (-1); | ||
115 | } | ||
116 | if (child > 0) | ||
117 | { | ||
118 | sleep (timeout); | ||
119 | printf ("Child processes were killed after timeout of %u seconds\n", | ||
120 | timeout); | ||
121 | kill (0, | ||
122 | SIGTERM); | ||
123 | exit (3); | ||
124 | } | ||
125 | exit (-1); | ||
126 | } | ||
127 | |||
128 | /* end of timeout_watchdog.c */ | ||