From: Vsevolod Stakhov Date: Tue, 28 Oct 2014 14:03:46 +0000 (+0000) Subject: Rework host/port/priority parsing. X-Git-Tag: 0.7.3~36^2~4 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=4a4ff2f073debbe1b5967121fc4e1782bd004ed6;p=rspamd.git Rework host/port/priority parsing. --- diff --git a/src/libserver/cfg_file.h b/src/libserver/cfg_file.h index 9366b7718..f9e2aa46e 100644 --- a/src/libserver/cfg_file.h +++ b/src/libserver/cfg_file.h @@ -15,11 +15,6 @@ #define DEFAULT_BIND_PORT 11333 #define DEFAULT_CONTROL_PORT 11334 -/* Upstream timeouts */ -#define DEFAULT_UPSTREAM_ERROR_TIME 10 -#define DEFAULT_UPSTREAM_ERROR_TIME 10 -#define DEFAULT_UPSTREAM_DEAD_TIME 300 -#define DEFAULT_UPSTREAM_MAXERRORS 10 struct expression; struct tokenizer; @@ -330,34 +325,6 @@ struct rspamd_config { }; -/** - * Parse host[:port[:priority]] line - * @param ina host address - * @param port port - * @param priority priority - * @return TRUE if string was parsed - */ -gboolean rspamd_parse_host_port_priority (rspamd_mempool_t *pool, - const gchar *str, gchar **addr, guint16 *port, guint *priority); - -/** - * Parse host:port line - * @param ina host address - * @param port port - * @return TRUE if string was parsed - */ -gboolean rspamd_parse_host_port (rspamd_mempool_t *pool, const gchar *str, - gchar **addr, guint16 *port); - -/** - * Parse host:priority line - * @param ina host address - * @param priority priority - * @return TRUE if string was parsed - */ -gboolean rspamd_parse_host_priority (rspamd_mempool_t *pool, const gchar *str, - gchar **addr, guint *priority); - /** * Parse bind credits * @param cf config file to use diff --git a/src/libserver/cfg_utils.c b/src/libserver/cfg_utils.c index d01fd2a0e..8d7988b01 100644 --- a/src/libserver/cfg_utils.c +++ b/src/libserver/cfg_utils.c @@ -53,180 +53,6 @@ static gchar * rspamd_ucl_read_cb (rspamd_mempool_t * pool, static void rspamd_ucl_fin_cb (rspamd_mempool_t * pool, struct map_cb_data *data); -static gboolean -parse_host_port_priority_strv (rspamd_mempool_t *pool, gchar **tokens, - gchar **addr, guint16 *port, guint *priority, guint default_port) -{ - gchar *err_str, portbuf[8]; - const gchar *cur_tok, *cur_port; - struct addrinfo hints, *res; - guint port_parsed, priority_parsed, saved_errno = errno; - gint r; - union { - struct sockaddr_in v4; - struct sockaddr_in6 v6; - } addr_holder; - - /* Now try to parse host and write address to ina */ - memset (&hints, 0, sizeof (hints)); - hints.ai_socktype = SOCK_STREAM; /* Type of the socket */ - hints.ai_flags = AI_NUMERICSERV; - - cur_tok = tokens[0]; - - if (strcmp (cur_tok, "*v6") == 0) { - hints.ai_family = AF_INET6; - hints.ai_flags |= AI_PASSIVE; - cur_tok = NULL; - } - else if (strcmp (cur_tok, "*v4") == 0) { - hints.ai_family = AF_INET; - hints.ai_flags |= AI_PASSIVE; - cur_tok = NULL; - } - else { - hints.ai_family = AF_UNSPEC; - } - - if (tokens[1] != NULL) { - /* Port part */ - rspamd_strlcpy (portbuf, tokens[1], sizeof (portbuf)); - cur_port = portbuf; - if (port != NULL) { - errno = 0; - port_parsed = strtoul (tokens[1], &err_str, 10); - if (*err_str != '\0' || errno != 0) { - msg_warn ("cannot parse port: %s, at symbol %c, error: %s", - tokens[1], - *err_str, - strerror (errno)); - hints.ai_flags ^= AI_NUMERICSERV; - } - else if (port_parsed > G_MAXUINT16) { - errno = ERANGE; - msg_warn ("cannot parse port: %s, error: %s", - tokens[1], - *err_str, - strerror (errno)); - hints.ai_flags ^= AI_NUMERICSERV; - } - else { - *port = port_parsed; - } - } - if (priority != NULL) { - const gchar *tok; - - if (port != NULL) { - tok = tokens[2]; - } - else { - tok = tokens[1]; - } - if (tok != NULL) { - /* Priority part */ - errno = 0; - priority_parsed = strtoul (tok, &err_str, 10); - if (*err_str != '\0' || errno != 0) { - msg_warn ( - "cannot parse priority: %s, at symbol %c, error: %s", - tok, - *err_str, - strerror (errno)); - } - else { - *priority = priority_parsed; - } - } - } - } - else if (default_port != 0) { - rspamd_snprintf (portbuf, sizeof (portbuf), "%ud", default_port); - cur_port = portbuf; - } - else { - cur_port = NULL; - } - - if ((r = getaddrinfo (cur_tok, cur_port, &hints, &res)) == 0) { - memcpy (&addr_holder, res->ai_addr, - MIN (sizeof (addr_holder), res->ai_addrlen)); - if (res->ai_family == AF_INET) { - if (pool != NULL) { - *addr = rspamd_mempool_alloc (pool, INET_ADDRSTRLEN + 1); - } - inet_ntop (res->ai_family, - &addr_holder.v4.sin_addr, - *addr, - INET_ADDRSTRLEN + 1); - } - else { - if (pool != NULL) { - *addr = rspamd_mempool_alloc (pool, INET6_ADDRSTRLEN + 1); - } - inet_ntop (res->ai_family, - &addr_holder.v6.sin6_addr, - *addr, - INET6_ADDRSTRLEN + 1); - } - freeaddrinfo (res); - } - else { - msg_err ("address resolution for %s failed: %s", - tokens[0], - gai_strerror (r)); - goto err; - } - - /* Restore errno */ - errno = saved_errno; - return TRUE; - -err: - errno = saved_errno; - return FALSE; -} - -gboolean -rspamd_parse_host_port_priority (rspamd_mempool_t *pool, - const gchar *str, - gchar **addr, - guint16 *port, - guint *priority) -{ - gchar **tokens; - gboolean ret; - - tokens = g_strsplit_set (str, ":", 0); - if (!tokens || !tokens[0]) { - return FALSE; - } - - ret = parse_host_port_priority_strv (pool, tokens, addr, port, priority, 0); - - g_strfreev (tokens); - - return ret; -} - -gboolean -rspamd_parse_host_port (rspamd_mempool_t *pool, - const gchar *str, - gchar **addr, - guint16 *port) -{ - return rspamd_parse_host_port_priority (pool, str, addr, port, NULL); -} - -gboolean -rspamd_parse_host_priority (rspamd_mempool_t *pool, - const gchar *str, - gchar **addr, - guint *priority) -{ - return rspamd_parse_host_port_priority (pool, str, addr, NULL, priority); -} - gboolean rspamd_parse_bind_line (struct rspamd_config *cfg, struct rspamd_worker_conf *cf, diff --git a/src/libutil/addr.c b/src/libutil/addr.c index a06dc2662..00b371ab2 100644 --- a/src/libutil/addr.c +++ b/src/libutil/addr.c @@ -182,3 +182,135 @@ rspamd_inet_address_connect (rspamd_inet_addr_t *addr, gint type, return fd; } + +gboolean +rspamd_parse_host_port_priority_strv (gchar **tokens, + rspamd_inet_addr_t *addr, guint *priority, guint default_port) +{ + gchar *err_str, portbuf[8]; + const gchar *cur_tok, *cur_port; + struct addrinfo hints, *res; + guint port_parsed, priority_parsed, saved_errno = errno; + gint r; + + /* Now try to parse host and write address to ina */ + memset (&hints, 0, sizeof (hints)); + hints.ai_socktype = SOCK_STREAM; /* Type of the socket */ + hints.ai_flags = AI_NUMERICSERV; + + cur_tok = tokens[0]; + + if (strcmp (cur_tok, "*v6") == 0) { + hints.ai_family = AF_INET6; + hints.ai_flags |= AI_PASSIVE; + cur_tok = NULL; + } + else if (strcmp (cur_tok, "*v4") == 0) { + hints.ai_family = AF_INET; + hints.ai_flags |= AI_PASSIVE; + cur_tok = NULL; + } + else { + hints.ai_family = AF_UNSPEC; + } + + if (tokens[1] != NULL) { + /* Port part */ + rspamd_strlcpy (portbuf, tokens[1], sizeof (portbuf)); + cur_port = portbuf; + errno = 0; + port_parsed = strtoul (tokens[1], &err_str, 10); + if (*err_str != '\0' || errno != 0) { + msg_warn ("cannot parse port: %s, at symbol %c, error: %s", + tokens[1], + *err_str, + strerror (errno)); + hints.ai_flags ^= AI_NUMERICSERV; + } + else if (port_parsed > G_MAXUINT16) { + errno = ERANGE; + msg_warn ("cannot parse port: %s, error: %s", + tokens[1], + *err_str, + strerror (errno)); + hints.ai_flags ^= AI_NUMERICSERV; + } + if (priority != NULL) { + const gchar *tok; + + tok = tokens[2]; + if (tok != NULL) { + /* Priority part */ + errno = 0; + priority_parsed = strtoul (tok, &err_str, 10); + if (*err_str != '\0' || errno != 0) { + msg_warn ( + "cannot parse priority: %s, at symbol %c, error: %s", + tok, + *err_str, + strerror (errno)); + } + else { + *priority = priority_parsed; + } + } + } + } + else if (default_port != 0) { + rspamd_snprintf (portbuf, sizeof (portbuf), "%ud", default_port); + cur_port = portbuf; + } + else { + cur_port = NULL; + } + + if ((r = getaddrinfo (cur_tok, cur_port, &hints, &res)) == 0) { + memcpy (&addr->addr, res->ai_addr, + MIN (sizeof (addr->addr), res->ai_addrlen)); + freeaddrinfo (res); + } + else { + msg_err ("address resolution for %s failed: %s", + tokens[0], + gai_strerror (r)); + goto err; + } + + /* Restore errno */ + errno = saved_errno; + return TRUE; + +err: + errno = saved_errno; + return FALSE; +} + +gboolean +rspamd_parse_host_port_priority ( + const gchar *str, + rspamd_inet_addr_t *addr, + guint *priority, + guint default_port) +{ + gchar **tokens; + gboolean ret; + + tokens = g_strsplit_set (str, ":", 0); + if (!tokens || !tokens[0]) { + return FALSE; + } + + ret = rspamd_parse_host_port_priority_strv (tokens, addr, priority, default_port); + + g_strfreev (tokens); + + return ret; +} + +gboolean +rspamd_parse_host_port (const gchar *str, + rspamd_inet_addr_t *addr, + guint default_port) +{ + return rspamd_parse_host_port_priority (str, addr, NULL, default_port); +} diff --git a/src/libutil/addr.h b/src/libutil/addr.h index 049cc88c3..706f2bf87 100644 --- a/src/libutil/addr.h +++ b/src/libutil/addr.h @@ -95,4 +95,27 @@ gboolean rspamd_ip_is_valid (rspamd_inet_addr_t *addr); */ gint rspamd_accept_from_socket (gint sock, rspamd_inet_addr_t *addr); +gboolean rspamd_parse_host_port_priority_strv (gchar **tokens, + rspamd_inet_addr_t *addr, guint *priority, guint default_port); + +/** + * Parse host[:port[:priority]] line + * @param ina host address + * @param port port + * @param priority priority + * @return TRUE if string was parsed + */ +gboolean rspamd_parse_host_port_priority (const gchar *str, + rspamd_inet_addr_t *addr, guint *priority, guint default_port); + +/** + * Parse host:port line + * @param ina host address + * @param port port + * @return TRUE if string was parsed + */ +gboolean rspamd_parse_host_port (const gchar *str, + rspamd_inet_addr_t *addr, guint default_port); + + #endif /* ADDR_H_ */