diff --git a/docs/reference/libinfinoted-plugin-manager/libinfinoted-plugin-manager-0.7-sections.txt b/docs/reference/libinfinoted-plugin-manager/libinfinoted-plugin-manager-0.7-sections.txt index 207c3316..5a166533 100644 --- a/docs/reference/libinfinoted-plugin-manager/libinfinoted-plugin-manager-0.7-sections.txt +++ b/docs/reference/libinfinoted-plugin-manager/libinfinoted-plugin-manager-0.7-sections.txt @@ -43,6 +43,7 @@ infinoted_parameter_convert_security_policy infinoted_parameter_convert_string infinoted_parameter_convert_string_list infinoted_parameter_convert_flags +infinoted_parameter_convert_ip_address INFINOTED_PARAMETER_TYPED_VALUE_TYPE infinoted_parameter_typed_value_get_type diff --git a/infinoted/infinoted-0.7.man b/infinoted/infinoted-0.7.man index 2e565cc4..8e93d9aa 100644 --- a/infinoted/infinoted-0.7.man +++ b/infinoted/infinoted-0.7.man @@ -43,6 +43,9 @@ Creates a new self\-signed certificate using the given key \fB\-p\fR, \fB\-\-port\-number\fR=\fIPORT\fR The port number to listen on .TP +\fB\-\-listen\-address\fR=\fIADDRESS\fR +The IP address to listen on +.TP \fB\-\-security\-policy\fR=\fIno\-tls\fR|allow\-tls|require\-tls How to decide whether to use TLS .TP diff --git a/infinoted/infinoted-options.c b/infinoted/infinoted-options.c index 82d25088..a43b12bc 100644 --- a/infinoted/infinoted-options.c +++ b/infinoted/infinoted-options.c @@ -92,6 +92,15 @@ const InfinotedParameterInfo INFINOTED_OPTIONS[] = { 'p', N_("The TCP port number to listen on."), N_("PORT") + }, { + "listen-address", + INFINOTED_PARAMETER_STRING, + 0, + offsetof(InfinotedOptions, listen_address), + infinoted_parameter_convert_ip_address, + 0, + N_("The IP address to listen on."), + N_("ADDRESS"), }, { "security-policy", INFINOTED_PARAMETER_STRING, @@ -962,6 +971,7 @@ infinoted_options_new(const gchar* const* config_files, options->create_key = FALSE; options->create_certificate = FALSE; options->port = inf_protocol_get_default_port(); + options->listen_address = NULL; options->security_policy = INF_XMPP_CONNECTION_SECURITY_ONLY_TLS; options->root_directory = g_build_filename(g_get_home_dir(), ".infinote", NULL); @@ -1003,6 +1013,7 @@ infinoted_options_free(InfinotedOptions* options) g_free(options->certificate_file); g_free(options->certificate_chain_file); g_free(options->root_directory); + inf_ip_address_free(options->listen_address); g_strfreev(options->plugins); g_free(options->password); #ifdef LIBINFINITY_HAVE_PAM diff --git a/infinoted/infinoted-options.h b/infinoted/infinoted-options.h index 0a6d3d33..75b8faab 100644 --- a/infinoted/infinoted-options.h +++ b/infinoted/infinoted-options.h @@ -39,6 +39,7 @@ struct _InfinotedOptions { gboolean create_key; gboolean create_certificate; guint port; + InfIpAddress *listen_address; InfXmppConnectionSecurityPolicy security_policy; gchar* root_directory; diff --git a/infinoted/infinoted-parameter.c b/infinoted/infinoted-parameter.c index c8dc74e6..72c4c403 100644 --- a/infinoted/infinoted-parameter.c +++ b/infinoted/infinoted-parameter.c @@ -524,6 +524,52 @@ infinoted_parameter_convert_port(gpointer out, return TRUE; } +/** + * infinoted_parameter_convert_ip_address: + * @out: (type InfIpAddress**) (out): The pointer to the output #InfIpAddress + * location. + * @in: (type gchar**) (in): The pointer to the input string location. + * @error: Location to store error information, if any, or %NULL. + * + * Converts the string that @in points to to an #InfIpAddress* value. If the + * string can not be converted to an IP address, the functions fails and @error + * is set. + * + * This is a #InfinotedParameterConvertFunc function that can be used for + * fields of type #InfIpAddress*. + * + * Returns: %TRUE on success, or %FALSE otherwise. + */ +gboolean +infinoted_parameter_convert_ip_address(gpointer out, + gpointer in, + GError** error) +{ + gchar** in_str; + InfIpAddress** out_val; + + in_str = (gchar**) in; + out_val = (InfIpAddress**) out; + + InfIpAddress *address = inf_ip_address_new_from_string(*in_str); + + if(address == NULL) + { + g_set_error_literal( + error, + infinoted_parameter_error_quark(), + INFINOTED_PARAMETER_ERROR_INVALID_IP_ADDRESS, + _("Invalid IP address") + ); + + return FALSE; + } + + *out_val = address; + + return TRUE; +} + /** * infinoted_parameter_convert_nonnegative: * @out: (type guint*) (out): The pointer to the output #guint. diff --git a/infinoted/infinoted-parameter.h b/infinoted/infinoted-parameter.h index 6540d015..c0543e46 100644 --- a/infinoted/infinoted-parameter.h +++ b/infinoted/infinoted-parameter.h @@ -109,8 +109,9 @@ struct _InfinotedParameterTypedValue { * infinoted_parameter_convert_boolean(), * infinoted_parameter_convert_port(), * infinoted_parameter_convert_nonnegative(), - * infinoted_parameter_convert_positive(), and - * infinoted_parameter_convert_security_policy(). + * infinoted_parameter_convert_positive(), + * infinoted_parameter_convert_security_policy() and + * infinoted_parameter_convert_ip_address(). * * Returns: %TRUE on success or %FALSE if an error occurred. */ @@ -160,6 +161,8 @@ struct _InfinotedParameterInfo { * @INFINOTED_PARAMETER_ERROR_INVALID_SECURITY_POLICY: A security policy given * as a parameter is not valid. The only allowed values are * "no-tls", "allow-tls", and "require-tls". + * @INFINOTED_PARAMETER_ERROR_INVALID_IP_ADDRESS: The value given as a + * parameter is not a valid IP address. * * Specifies the possible error conditions for errors in the * INFINOTED_PARAMETER_ERROR domain. These typically @@ -169,7 +172,8 @@ typedef enum _InfinotedParameterError { INFINOTED_PARAMETER_ERROR_REQUIRED, INFINOTED_PARAMETER_ERROR_INVALID_NUMBER, INFINOTED_PARAMETER_ERROR_INVALID_FLAG, - INFINOTED_PARAMETER_ERROR_INVALID_SECURITY_POLICY + INFINOTED_PARAMETER_ERROR_INVALID_SECURITY_POLICY, + INFINOTED_PARAMETER_ERROR_INVALID_IP_ADDRESS } InfinotedParameterError; GQuark @@ -240,6 +244,11 @@ infinoted_parameter_convert_flags(gpointer out, const GFlagsValue* values, GError** error); +gboolean +infinoted_parameter_convert_ip_address(gpointer out, + gpointer in, + GError** error); + G_END_DECLS #endif /* __INFINOTED_PARAMETER_H__ */ diff --git a/infinoted/infinoted-run.c b/infinoted/infinoted-run.c index a520f93c..89220a2e 100644 --- a/infinoted/infinoted-run.c +++ b/infinoted/infinoted-run.c @@ -249,18 +249,40 @@ infinoted_run_new(InfinotedStartup* startup, g_object_unref(xmpp_manager); #endif - address = inf_ip_address_new_raw6(INFINOTED_RUN_IPV6_ANY_ADDR); - run->xmpp6 = infinoted_run_create_server(run, startup, address, NULL); - local_error = NULL; - run->xmpp4 = infinoted_run_create_server(run, startup, NULL, &local_error); + + if(startup->options->listen_address != NULL) + { + /* Use manually specified listen address */ + address = inf_ip_address_copy(startup->options->listen_address); + + switch(inf_ip_address_get_family(address)) + { + case INF_IP_ADDRESS_IPV4: + run->xmpp4 = infinoted_run_create_server(run, startup, address, &local_error); + run->xmpp6 = NULL; + break; + case INF_IP_ADDRESS_IPV6: + run->xmpp4 = NULL; + run->xmpp6 = infinoted_run_create_server(run, startup, address, &local_error); + break; + } + } + else + { + address = inf_ip_address_new_raw6(INFINOTED_RUN_IPV6_ANY_ADDR); + + run->xmpp6 = infinoted_run_create_server(run, startup, address, NULL); + run->xmpp4 = infinoted_run_create_server(run, startup, NULL, &local_error); + } if(run->xmpp4 == NULL) { /* Ignore if we have an IPv6 server running */ if(run->xmpp6 != NULL) { - g_error_free(local_error); + if(local_error != NULL) + g_error_free(local_error); } else { @@ -272,7 +294,7 @@ infinoted_run_new(InfinotedStartup* startup, g_object_unref(run->directory); g_object_unref(run->io); g_slice_free(InfinotedRun, run); - return NULL; + run = NULL; } }