Merge pull request #2 from nm-mrt/dns-support

Handle no DNS at system start
This commit is contained in:
Tobias Hintze 2016-03-25 13:16:20 +01:00
commit ad27e80521
4 changed files with 90 additions and 36 deletions

View File

@ -11,6 +11,7 @@
/* */
#define CAPWAP_MACADDRESS_EUI48_BUFFER 18
#define CAPWAP_MACADDRESS_EUI64_BUFFER 24
#define CAPWAP_MAX_FQDN_SIZE 256
/* */
union sockaddr_capwap {
@ -20,6 +21,12 @@ union sockaddr_capwap {
struct sockaddr_storage ss;
};
struct addr_capwap {
char fqdn[CAPWAP_MAX_FQDN_SIZE];
union sockaddr_capwap sockaddr;
char resolved;
};
/* Helper */
#define CAPWAP_GET_NETWORK_PORT(addr) ntohs((((addr)->ss.ss_family == AF_INET) ? (addr)->sin.sin_port : (((addr)->ss.ss_family == AF_INET6) ? (addr)->sin6.sin6_port : 0)))
#define CAPWAP_SET_NETWORK_PORT(addr, port) if ((addr)->ss.ss_family == AF_INET) { \

View File

@ -75,8 +75,8 @@ static int wtp_init(void) {
/* AC information */
g_wtp.discoverytype.type = CAPWAP_DISCOVERYTYPE_TYPE_UNKNOWN;
g_wtp.acdiscoveryrequest = 1;
g_wtp.acdiscoveryarray = capwap_array_create(sizeof(union sockaddr_capwap), 0, 0);
g_wtp.acpreferedarray = capwap_array_create(sizeof(union sockaddr_capwap), 0, 0);
g_wtp.acdiscoveryarray = capwap_array_create(sizeof(struct addr_capwap), 0, 0);
g_wtp.acpreferedarray = capwap_array_create(sizeof(struct addr_capwap), 0, 0);
g_wtp.acdiscoveryresponse = capwap_array_create(sizeof(struct wtp_discovery_response), 0, 1);
/* Radios */
@ -136,14 +136,15 @@ static void wtp_destroy(void) {
/* */
static void wtp_add_default_acaddress() {
union sockaddr_capwap address;
struct addr_capwap address;
/* Broadcast IPv4 */
memset(&address, 0, sizeof(union sockaddr_capwap));
address.sin.sin_family = AF_INET;
address.sin.sin_addr.s_addr = INADDR_BROADCAST;
address.sin.sin_port = htons(CAPWAP_CONTROL_PORT);
memcpy(capwap_array_get_item_pointer(g_wtp.acdiscoveryarray, g_wtp.acdiscoveryarray->count), &address, sizeof(union sockaddr_capwap));
memset(&address, 0, sizeof(struct addr_capwap));
address.resolved = 1;
address.sockaddr.sin.sin_family = AF_INET;
address.sockaddr.sin.sin_addr.s_addr = INADDR_BROADCAST;
address.sockaddr.sin.sin_port = htons(CAPWAP_CONTROL_PORT);
memcpy(capwap_array_get_item_pointer(g_wtp.acdiscoveryarray, g_wtp.acdiscoveryarray->count), &address, sizeof(struct addr_capwap));
/* Multicast IPv4 */
/* TODO */
@ -1202,20 +1203,22 @@ static int wtp_parsing_configuration_1_0(config_t* config) {
for (i = 0; i < count; i++) {
const char* address = config_setting_get_string_elem(configSetting, i);
if (address != NULL) {
union sockaddr_capwap acaddr;
struct addr_capwap acaddr;
memset(&acaddr, 0, sizeof(struct addr_capwap));
strncpy(acaddr.fqdn, address, CAPWAP_MAX_FQDN_SIZE-1);
acaddr.resolved = 0;
/* Parsing address */
if (capwap_address_from_string(address, &acaddr)) {
if (!CAPWAP_GET_NETWORK_PORT(&acaddr)) {
CAPWAP_SET_NETWORK_PORT(&acaddr, CAPWAP_CONTROL_PORT);
if (capwap_address_from_string(address, &acaddr.sockaddr)) {
if (!CAPWAP_GET_NETWORK_PORT(&acaddr.sockaddr)) {
CAPWAP_SET_NETWORK_PORT(&acaddr.sockaddr, CAPWAP_CONTROL_PORT);
}
memcpy(capwap_array_get_item_pointer(g_wtp.acdiscoveryarray, g_wtp.acdiscoveryarray->count), &acaddr, sizeof(union sockaddr_capwap));
acaddr.resolved = 1;
g_wtp.discoverytype.type = CAPWAP_DISCOVERYTYPE_TYPE_STATIC;
} else {
capwap_logging_error("Invalid configuration file, invalid application.acdiscovery.host value");
return 0;
capwap_logging_info("%s:%d Could not resolve application.acdiscovery.host %s", __FILE__, __LINE__, address);
}
memcpy(capwap_array_get_item_pointer(g_wtp.acdiscoveryarray, g_wtp.acdiscoveryarray->count), &acaddr, sizeof(struct addr_capwap));
}
}
}
@ -1228,19 +1231,21 @@ static int wtp_parsing_configuration_1_0(config_t* config) {
for (i = 0; i < count; i++) {
const char* address = config_setting_get_string_elem(configSetting, i);
if (address != NULL) {
union sockaddr_capwap acaddr;
struct addr_capwap acaddr;
memset(&acaddr, 0, sizeof(struct addr_capwap));
strncpy(acaddr.fqdn, address, CAPWAP_MAX_FQDN_SIZE-1);
acaddr.resolved = 0;
/* Parsing address */
if (capwap_address_from_string(address, &acaddr)) {
if (!CAPWAP_GET_NETWORK_PORT(&acaddr)) {
CAPWAP_SET_NETWORK_PORT(&acaddr, CAPWAP_CONTROL_PORT);
if (capwap_address_from_string(address, &acaddr.sockaddr)) {
if (!CAPWAP_GET_NETWORK_PORT(&acaddr.sockaddr)) {
CAPWAP_SET_NETWORK_PORT(&acaddr.sockaddr, CAPWAP_CONTROL_PORT);
}
memcpy(capwap_array_get_item_pointer(g_wtp.acpreferedarray, g_wtp.acpreferedarray->count), &acaddr, sizeof(union sockaddr_capwap));
acaddr.resolved = 1;
} else {
capwap_logging_error("Invalid configuration file, invalid application.acprefered.host value");
return 0;
capwap_logging_info("%s:%d Could not resolve application.acprefered.host %s", __FILE__, __LINE__, acaddr.fqdn);
}
memcpy(capwap_array_get_item_pointer(g_wtp.acpreferedarray, g_wtp.acpreferedarray->count), &acaddr, sizeof(struct addr_capwap));
}
}
}

View File

@ -49,9 +49,18 @@ void wtp_dfa_state_discovery_timeout(struct capwap_timeout* timeout, unsigned lo
/* Check for preferred AC */
for (j = 0; j < ((indexpreferred != -1) ? indexpreferred : g_wtp.acpreferedarray->count); j++) {
union sockaddr_capwap* acpreferredaddr = (union sockaddr_capwap*)capwap_array_get_item_pointer(g_wtp.acpreferedarray, j);
if (!capwap_compare_ip(acpreferredaddr, &checkaddr)) {
struct addr_capwap* acpreferredaddr = (struct addr_capwap*)capwap_array_get_item_pointer(g_wtp.acpreferedarray, j);
if (!acpreferredaddr->resolved) {
if (capwap_address_from_string(acpreferredaddr->fqdn, &acpreferredaddr->sockaddr)) {
if (!CAPWAP_GET_NETWORK_PORT(&acpreferredaddr->sockaddr)) {
CAPWAP_SET_NETWORK_PORT(&acpreferredaddr->sockaddr, CAPWAP_CONTROL_PORT);
}
acpreferredaddr->resolved = 1;
} else {
capwap_logging_info("%s:%d Could not resolve application.acprefered.host %s", __FILE__, __LINE__, acpreferredaddr->fqdn);
}
}
if (!capwap_compare_ip(&acpreferredaddr->sockaddr, &checkaddr)) {
indexpreferred = j;
memcpy(&peeraddr, &checkaddr, sizeof(union sockaddr_capwap));
break;
@ -79,9 +88,18 @@ void wtp_dfa_state_discovery_timeout(struct capwap_timeout* timeout, unsigned lo
/* Check for preferred AC */
for (j = 0; j < ((indexpreferred != -1) ? indexpreferred : g_wtp.acpreferedarray->count); j++) {
union sockaddr_capwap* acpreferredaddr = (union sockaddr_capwap*)capwap_array_get_item_pointer(g_wtp.acpreferedarray, j);
if (!capwap_compare_ip(acpreferredaddr, &checkaddr)) {
struct addr_capwap* acpreferredaddr = (struct addr_capwap*)capwap_array_get_item_pointer(g_wtp.acpreferedarray, j);
if (!acpreferredaddr->resolved) {
if (capwap_address_from_string(acpreferredaddr->fqdn, &acpreferredaddr->sockaddr)) {
if (!CAPWAP_GET_NETWORK_PORT(&acpreferredaddr->sockaddr)) {
CAPWAP_SET_NETWORK_PORT(&acpreferredaddr->sockaddr, CAPWAP_CONTROL_PORT);
}
acpreferredaddr->resolved = 1;
} else {
capwap_logging_info("Could not resolve application.acprefered.host %s", acpreferredaddr->fqdn);
}
}
if (!capwap_compare_ip(&acpreferredaddr->sockaddr, &checkaddr)) {
indexpreferred = j;
memcpy(&peeraddr, &checkaddr, sizeof(union sockaddr_capwap));
break;
@ -183,8 +201,20 @@ void wtp_dfa_state_discovery_timeout(struct capwap_timeout* timeout, unsigned lo
/* Send discovery request to AC */
for (i = 0; i < g_wtp.acdiscoveryarray->count; i++) {
if (!capwap_sendto_fragmentpacket(g_wtp.net.socket, g_wtp.requestfragmentpacket, (union sockaddr_capwap*)capwap_array_get_item_pointer(g_wtp.acdiscoveryarray, i))) {
capwap_logging_debug("Warning: error to send discovery request packet");
struct addr_capwap* addr = capwap_array_get_item_pointer(g_wtp.acdiscoveryarray, i);
if (!addr->resolved) {
if (capwap_address_from_string(addr->fqdn, &addr->sockaddr)) {
if (!CAPWAP_GET_NETWORK_PORT(&addr->sockaddr)) {
CAPWAP_SET_NETWORK_PORT(&addr->sockaddr, CAPWAP_CONTROL_PORT);
}
addr->resolved = 1;
g_wtp.discoverytype.type = CAPWAP_DISCOVERYTYPE_TYPE_STATIC;
} else {
capwap_logging_info("%s:%d Could not resolve application.acdiscovery.host %s", __FILE__, __LINE__, addr->fqdn);
}
}
if (!capwap_sendto_fragmentpacket(g_wtp.net.socket, g_wtp.requestfragmentpacket, &addr->sockaddr)) {
capwap_logging_info("Error to send discovery request packet");
}
}

View File

@ -12,11 +12,12 @@ static int wtp_join_prefered_ac()
while (g_wtp.acpreferedselected < g_wtp.acpreferedarray->count)
{
union sockaddr_capwap localaddr;
union sockaddr_capwap *peeraddr;
struct addr_capwap *peeraddr;
/* Found in configuration file the AC address */
peeraddr = capwap_array_get_item_pointer(g_wtp.acpreferedarray,
g_wtp.acpreferedselected);
g_wtp.acpreferedselected);
/* Next AC */
g_wtp.acpreferedselected++;
@ -28,7 +29,18 @@ static int wtp_join_prefered_ac()
return -1;
}
if (capwap_connect_socket(&g_wtp.net, peeraddr) < 0) {
if(!peeraddr->resolved) {
if (capwap_address_from_string(peeraddr->fqdn, &peeraddr->sockaddr)) {
if (!CAPWAP_GET_NETWORK_PORT(&peeraddr->sockaddr)) {
CAPWAP_SET_NETWORK_PORT(&peeraddr->sockaddr, CAPWAP_CONTROL_PORT);
}
peeraddr->resolved = 1;
} else {
capwap_logging_info("%s:%d Could not resolve application.acprefered.host %s", __FILE__, __LINE__, peeraddr->fqdn);
}
}
if (capwap_connect_socket(&g_wtp.net, &peeraddr->sockaddr) < 0) {
capwap_logging_fatal("Cannot bind control address");
capwap_close_sockets(&g_wtp.net);
return -1;
@ -42,7 +54,7 @@ static int wtp_join_prefered_ac()
}
/* */
capwap_crypt_setconnection(&g_wtp.dtls, g_wtp.net.socket, &localaddr, peeraddr);
capwap_crypt_setconnection(&g_wtp.dtls, g_wtp.net.socket, &localaddr, &peeraddr->sockaddr);
/* */
if (!g_wtp.enabledtls) {