diff options
Diffstat (limited to 'shared')
| -rw-r--r-- | shared/config-parser.c | 44 | ||||
| -rw-r--r-- | shared/config-parser.h | 2 | ||||
| -rw-r--r-- | shared/utils.c | 22 | ||||
| -rw-r--r-- | shared/utils.h | 2 | 
4 files changed, 51 insertions, 19 deletions
diff --git a/shared/config-parser.c b/shared/config-parser.c index f249cda..ea800ad 100644 --- a/shared/config-parser.c +++ b/shared/config-parser.c @@ -148,7 +148,7 @@ bool scfg_async_dns_start(struct server_config *scfg)  }  static void scfg_queue_dns(struct server_config *scfg, struct cfg_value *value, -			   struct list_head *target_list) +			   struct list_head *target_list, bool any_ok)  {  	struct saddr *saddr, *tmp;  	struct dns_async *dns; @@ -158,6 +158,8 @@ static void scfg_queue_dns(struct server_config *scfg, struct cfg_value *value,  		debug(DBG_DNS, "got sync results");  		list_for_each_entry_safe(saddr, tmp, &value->saddrs, list) {  			list_del(&saddr->list); +			if (!any_ok) +				saddr_any_to_loopback(saddr);  			list_add(&saddr->list, target_list);  		}  		break; @@ -244,8 +246,11 @@ bool scfg_validate(struct server_config *scfg, const char **error)  		if (list_empty(&scfg->locals))  			ERROR("missing local addresses for proxy server"); +		/* FIXME: Reinstate once server.properties parsing is implemented */ +		/*  		if (list_empty(&scfg->remotes))  			ERROR("missing remote addresses for proxy server"); +		*/  		list_for_each_entry(saddr, &scfg->locals, list) {  			port = saddr_port(saddr); @@ -323,12 +328,10 @@ static char *systemd_object_path(const char *service)  bool scfg_parse(struct server_config *scfg, char *buf, bool async,  		unsigned *lineno, const char **error)  { -	char *pos; +	char *pos = buf;  	assert_return(scfg && buf && lineno && error, false); -	pos = buf; -  	*lineno = 0;  	if (!config_parse_header(SERVER_CFG_HEADER, &pos, lineno)) @@ -340,11 +343,11 @@ bool scfg_parse(struct server_config *scfg, char *buf, bool async,  		struct cfg_value value;  		if (!config_parse_line(scfg->filename, &pos, scfg_key_map, &key, -				       &keyname, &value, async, lineno)) +				       &keyname, &value, async, lineno, error))  			break;  		if (key == SCFG_KEY_INVALID) -			ERROR("invalid line in config file"); +			return false;  		debug(DBG_CFG, "%s: key %s", scfg->filename, keyname); @@ -390,11 +393,11 @@ bool scfg_parse(struct server_config *scfg, char *buf, bool async,  			break;  		case SCFG_KEY_LOCAL: -			scfg_queue_dns(scfg, &value, &scfg->locals); +			scfg_queue_dns(scfg, &value, &scfg->locals, true);  			break;  		case SCFG_KEY_REMOTE: -			scfg_queue_dns(scfg, &value, &scfg->remotes); +			scfg_queue_dns(scfg, &value, &scfg->remotes, false);  			break;  		case SCFG_KEY_IDLE_TIMEOUT: @@ -443,7 +446,7 @@ bool scfg_parse(struct server_config *scfg, char *buf, bool async,  			break;  		case SCFG_KEY_RCON: -			scfg_queue_dns(scfg, &value, &scfg->rcons); +			scfg_queue_dns(scfg, &value, &scfg->rcons, false);  			break;  		case SCFG_KEY_RCON_PASSWORD: @@ -742,7 +745,7 @@ bool strtosockaddrs(const char *str, struct cfg_value *rvalue, bool async)  		if (!saddr)  			goto error; -		saddr_set_ipv4(saddr, INADDR_ANY, htons(port)); +		saddr_set_ipv4(saddr, htonl(INADDR_ANY), htons(port));  		list_add(&saddr->list, list);  		naddrs++; @@ -776,7 +779,7 @@ bool strtosockaddrs(const char *str, struct cfg_value *rvalue, bool async)  		if (!cfg_dns_lookup(str, port, rvalue, &naddrs, async))  			goto error; -	} else if (strtou16_strict(tmp, &port) == 0) { +	} else if (strtou16_strict(str, &port) == 0) {  		/* Port */  		debug(DBG_CFG, "attempting to parse a port number (%s)", str); @@ -792,12 +795,13 @@ bool strtosockaddrs(const char *str, struct cfg_value *rvalue, bool async)  		if (!saddr)  			goto error; -		saddr_set_ipv4(saddr, INADDR_ANY, htons(port)); +		saddr_set_ipv4(saddr, htonl(INADDR_ANY), htons(port));  		list_add(&saddr->list, list);  		naddrs++;  	} else {  		/* Unknown */ +		debug(DBG_CFG, "cannot parse str (%s)", str);  		goto error;  	} @@ -838,15 +842,16 @@ error:  bool config_parse_line(const char *filename, char **buf,  		       struct cfg_key_value_map *kvmap, int *rkey,  		       const char **rkeyname, struct cfg_value *rvalue, -		       bool async_dns, unsigned *lineno) +		       bool async_dns, unsigned *lineno, const char **error)  {  	char *line, *pos, *key, *value;  	size_t linelen;  	int i; -	assert_return(buf && *buf && kvmap && rkey && rkeyname && rvalue && lineno, -		      false); +	assert_return(buf && *buf && kvmap && rkey && rkeyname && rvalue && +		      lineno && error, false); +	*error = NULL;  	line = get_line(buf, lineno);  	if (!line)  		return false; @@ -902,8 +907,10 @@ bool config_parse_line(const char *filename, char **buf,  		_fallthrough_;  	case CFG_VAL_TYPE_ADDRS: -		if (!strtosockaddrs(value, rvalue, async_dns)) +		if (!strtosockaddrs(value, rvalue, async_dns)) { +			*error = "Failed to parse address/port line";  			goto error; +		}  		switch (rvalue->type) {  		case CFG_VAL_TYPE_ADDRS: @@ -940,7 +947,7 @@ bool config_parse_line(const char *filename, char **buf,  			rvalue->type = CFG_VAL_TYPE_BOOL;  			rvalue->boolean = false;  		} else { -			error("invalid boolean value (%s)", value); +			*error = "invalid boolean value";  			goto error;  		}  		break; @@ -965,7 +972,8 @@ bool config_parse_line(const char *filename, char **buf,  	return true;  error: -	error("%s: invalid config line: %u:%s", filename, *lineno, line); +	if (!*error) +		*error = "invalid line";  	rvalue->type = CFG_VAL_TYPE_INVALID;  	*rkey = 0;  	*rkeyname = NULL; diff --git a/shared/config-parser.h b/shared/config-parser.h index 7d0595d..129e085 100644 --- a/shared/config-parser.h +++ b/shared/config-parser.h @@ -111,7 +111,7 @@ bool strtosockaddrs(const char *str, struct cfg_value *rvalue, bool async);  bool config_parse_line(const char *filename, char **buf,  		       struct cfg_key_value_map *kvmap, int *rkey,  		       const char **rkeyname, struct cfg_value *rvalue, -		       bool async_dns, unsigned *lineno); +		       bool async_dns, unsigned *lineno, const char **error);  bool config_parse_header(const char *title, char **buf, unsigned *lineno); diff --git a/shared/utils.c b/shared/utils.c index 6474e30..9bf8cd8 100644 --- a/shared/utils.c +++ b/shared/utils.c @@ -141,6 +141,28 @@ void saddr_set_ipv6(struct saddr *saddr, const struct in6_addr *ip,  	saddr_set_addrstr(saddr);  } +void saddr_any_to_loopback(struct saddr *saddr) +{ +	switch (saddr->st.ss_family) { +	case AF_INET: +		if (saddr->in4.sin_addr.s_addr != htonl(INADDR_ANY)) +			return; +		saddr->in4.sin_addr.s_addr = htonl(INADDR_LOOPBACK); +		break; + +	case AF_INET6: +		if (memcmp(&saddr->in6.sin6_addr, &in6addr_any, +			   sizeof(in6addr_any))) +			return; +		saddr->in6.sin6_addr = in6addr_loopback; +		break; + +	default: +		return; +	} +	saddr_set_addrstr(saddr); +} +  void saddr_set_addrstr(struct saddr *saddr)  {  	// assert_return(saddr); diff --git a/shared/utils.h b/shared/utils.h index c47f9a5..bf1b63a 100644 --- a/shared/utils.h +++ b/shared/utils.h @@ -83,6 +83,8 @@ void saddr_set_ipv4(struct saddr *saddr, in_addr_t ip, in_port_t port);  void saddr_set_ipv6(struct saddr *saddr, const struct in6_addr *ip,  		    in_port_t port); +void saddr_any_to_loopback(struct saddr *saddr); +  void saddr_set_addrstr(struct saddr *saddr);  int strtou16_strict(const char *str, uint16_t *result);  | 
