2 This file is part of GNUnet.
3 Copyright (C) 2007-2017 GNUnet e.V.
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
22 * @author Christian Grothoff
23 * @author Milan Bouchet-Valat
25 * @file nat-auto/nat_auto_api.c
26 * Routines for NAT auto configuration.
29 #include "gnunet_nat_service.h"
30 #include "gnunet_nat_auto_service.h"
36 * Handle to auto-configuration in progress.
38 struct GNUNET_NAT_AUTO_AutoHandle
42 * Configuration we use.
44 const struct GNUNET_CONFIGURATION_Handle *cfg;
47 * Message queue for communicating with the NAT service.
49 struct GNUNET_MQ_Handle *mq;
52 * Function called with the result from the autoconfiguration.
54 GNUNET_NAT_AUTO_AutoResultCallback arc;
65 * Converts `enum GNUNET_NAT_StatusCode` to string
67 * @param err error code to resolve to a string
68 * @return point to a static string containing the error code
71 GNUNET_NAT_AUTO_status2string (enum GNUNET_NAT_StatusCode err)
75 case GNUNET_NAT_ERROR_SUCCESS:
76 return _ ("Operation Successful");
77 case GNUNET_NAT_ERROR_IPC_FAILURE:
78 return _ ("IPC failure");
79 case GNUNET_NAT_ERROR_INTERNAL_NETWORK_ERROR:
80 return _ ("Failure in network subsystem, check permissions.");
81 case GNUNET_NAT_ERROR_TIMEOUT:
82 return _ ("Encountered timeout while performing operation");
83 case GNUNET_NAT_ERROR_NOT_ONLINE:
84 return _ ("detected that we are offline");
85 case GNUNET_NAT_ERROR_UPNPC_NOT_FOUND:
86 return _ ("`upnpc` command not found");
87 case GNUNET_NAT_ERROR_UPNPC_FAILED:
88 return _ ("Failed to run `upnpc` command");
89 case GNUNET_NAT_ERROR_UPNPC_TIMEOUT:
90 return _ ("`upnpc' command took too long, process killed");
91 case GNUNET_NAT_ERROR_UPNPC_PORTMAP_FAILED:
92 return _ ("`upnpc' command failed to establish port mapping");
93 case GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_NOT_FOUND:
94 return _ ("`external-ip' command not found");
95 case GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_FAILED:
96 return _ ("Failed to run `external-ip` command");
97 case GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_OUTPUT_INVALID:
98 return _ ("`external-ip' command output invalid");
99 case GNUNET_NAT_ERROR_EXTERNAL_IP_ADDRESS_INVALID:
100 return _ ("no valid address was returned by `external-ip'");
101 case GNUNET_NAT_ERROR_NO_VALID_IF_IP_COMBO:
102 return _ ("Could not determine interface with internal/local network address");
103 case GNUNET_NAT_ERROR_HELPER_NAT_SERVER_NOT_FOUND:
104 return _ ("No functioning gnunet-helper-nat-server installation found");
105 case GNUNET_NAT_ERROR_NAT_TEST_START_FAILED:
106 return _ ("NAT test could not be initialized");
107 case GNUNET_NAT_ERROR_NAT_TEST_TIMEOUT:
108 return _ ("NAT test timeout reached");
109 case GNUNET_NAT_ERROR_NAT_REGISTER_FAILED:
110 return _ ("could not register NAT");
111 case GNUNET_NAT_ERROR_HELPER_NAT_CLIENT_NOT_FOUND:
112 return _ ("No working gnunet-helper-nat-client installation found");
114 return "unknown status code";
120 * Check result from autoconfiguration attempt.
122 * @param cls the `struct GNUNET_NAT_AUTO_AutoHandle`
123 * @param res the result
124 * @return #GNUNET_OK if @a res is well-formed (always for now)
127 check_auto_result (void *cls,
128 const struct GNUNET_NAT_AUTO_AutoconfigResultMessage *res)
135 * Handle result from autoconfiguration attempt.
137 * @param cls the `struct GNUNET_NAT_AUTO_AutoHandle`
138 * @param res the result
141 handle_auto_result (void *cls,
142 const struct GNUNET_NAT_AUTO_AutoconfigResultMessage *res)
144 struct GNUNET_NAT_AUTO_AutoHandle *ah = cls;
146 struct GNUNET_CONFIGURATION_Handle *cfg;
147 enum GNUNET_NAT_Type type
148 = (enum GNUNET_NAT_Type) ntohl (res->type);
149 enum GNUNET_NAT_StatusCode status
150 = (enum GNUNET_NAT_StatusCode) ntohl (res->status_code);
152 left = ntohs (res->header.size) - sizeof (*res);
153 cfg = GNUNET_CONFIGURATION_create ();
155 GNUNET_CONFIGURATION_deserialize (cfg,
156 (const char *) &res[1],
161 ah->arc (ah->arc_cls,
163 GNUNET_NAT_ERROR_IPC_FAILURE,
168 ah->arc (ah->arc_cls,
173 GNUNET_CONFIGURATION_destroy (cfg);
174 GNUNET_NAT_AUTO_autoconfig_cancel (ah);
179 * Handle queue errors by reporting autoconfiguration failure.
181 * @param cls the `struct GNUNET_NAT_AUTO_AutoHandle *`
182 * @param error details about the error
185 ah_error_handler (void *cls,
186 enum GNUNET_MQ_Error error)
188 struct GNUNET_NAT_AUTO_AutoHandle *ah = cls;
190 ah->arc (ah->arc_cls,
192 GNUNET_NAT_ERROR_IPC_FAILURE,
193 GNUNET_NAT_TYPE_UNKNOWN);
194 GNUNET_NAT_AUTO_autoconfig_cancel (ah);
199 * Start auto-configuration routine. The transport adapters should
200 * be stopped while this function is called.
202 * @param cfg initial configuration
203 * @param cb function to call with autoconfiguration result
204 * @param cb_cls closure for @a cb
205 * @return handle to cancel operation
207 struct GNUNET_NAT_AUTO_AutoHandle *
208 GNUNET_NAT_AUTO_autoconfig_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
209 GNUNET_NAT_AUTO_AutoResultCallback cb,
212 struct GNUNET_NAT_AUTO_AutoHandle *ah = GNUNET_new (struct GNUNET_NAT_AUTO_AutoHandle);
213 struct GNUNET_MQ_MessageHandler handlers[] = {
214 GNUNET_MQ_hd_var_size (auto_result,
215 GNUNET_MESSAGE_TYPE_NAT_AUTO_CFG_RESULT,
216 struct GNUNET_NAT_AUTO_AutoconfigResultMessage,
218 GNUNET_MQ_handler_end ()
220 struct GNUNET_MQ_Envelope *env;
221 struct GNUNET_NAT_AUTO_AutoconfigRequestMessage *req;
225 buf = GNUNET_CONFIGURATION_serialize (cfg,
227 if (size > GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (*req))
235 ah->arc_cls = cb_cls;
236 ah->mq = GNUNET_CLIENT_connecT (cfg,
248 env = GNUNET_MQ_msg_extra (req,
250 GNUNET_MESSAGE_TYPE_NAT_AUTO_REQUEST_CFG);
251 GNUNET_memcpy (&req[1],
255 GNUNET_MQ_send (ah->mq,
262 * Abort autoconfiguration.
264 * @param ah handle for operation to abort
267 GNUNET_NAT_AUTO_autoconfig_cancel (struct GNUNET_NAT_AUTO_AutoHandle *ah)
269 GNUNET_MQ_destroy (ah->mq);
273 /* end of nat_api_auto.c */