The capwap data channel migrated from userspace to kernalspace
This commit is contained in:
@ -28,76 +28,62 @@ void wtp_dfa_state_discovery_timeout(struct capwap_timeout* timeout, unsigned lo
|
||||
int i, j, w;
|
||||
int countwtp = -1;
|
||||
int indexpreferred = -1;
|
||||
|
||||
struct sockaddr_storage checkaddr;
|
||||
struct sockaddr_in* checkaddripv4;
|
||||
struct sockaddr_in6* checkaddripv6;
|
||||
union sockaddr_capwap checkaddr;
|
||||
union sockaddr_capwap peeraddr;
|
||||
|
||||
/* */
|
||||
g_wtp.acctrladdress.ss_family = AF_UNSPEC;
|
||||
peeraddr.ss.ss_family = AF_UNSPEC;
|
||||
|
||||
/* Selected by preferred or less WTP by AC */
|
||||
for (i = 0; i < g_wtp.acdiscoveryresponse->count; i++) {
|
||||
struct wtp_discovery_response* response = (struct wtp_discovery_response*)capwap_array_get_item_pointer(g_wtp.acdiscoveryresponse, i);
|
||||
|
||||
/* AC with IPv4 */
|
||||
if ((g_wtp.net.sock_family == AF_UNSPEC) || (g_wtp.net.sock_family == AF_INET)) {
|
||||
for (w = 0; w < response->controlipv4->count; w++) {
|
||||
struct capwap_controlipv4_element* controlipv4 = (struct capwap_controlipv4_element*)capwap_array_get_item_pointer(response->controlipv4, w);
|
||||
for (w = 0; w < response->controlipv4->count; w++) {
|
||||
struct capwap_controlipv4_element* controlipv4 = (struct capwap_controlipv4_element*)capwap_array_get_item_pointer(response->controlipv4, w);
|
||||
|
||||
/* Create IPv4 address */
|
||||
memset(&checkaddr, 0, sizeof(struct sockaddr_storage));
|
||||
checkaddripv4 = (struct sockaddr_in*)&checkaddr;
|
||||
checkaddripv4->sin_family = AF_INET;
|
||||
checkaddripv4->sin_port = htons(CAPWAP_CONTROL_PORT);
|
||||
memcpy(&checkaddripv4->sin_addr, &controlipv4->address, sizeof(struct in_addr));
|
||||
/* Create IPv4 address */
|
||||
checkaddr.sin.sin_family = AF_INET;
|
||||
memcpy(&checkaddr.sin.sin_addr, &controlipv4->address, sizeof(struct in_addr));
|
||||
checkaddr.sin.sin_port = htons(CAPWAP_CONTROL_PORT);
|
||||
|
||||
/* Check for preferred AC */
|
||||
for (j = 0; j < ((indexpreferred != -1) ? indexpreferred : g_wtp.acpreferedarray->count); j++) {
|
||||
struct sockaddr_storage* acpreferredaddr = (struct sockaddr_storage*)capwap_array_get_item_pointer(g_wtp.acpreferedarray, j);
|
||||
/* 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)) {
|
||||
indexpreferred = j;
|
||||
memcpy(&g_wtp.acctrladdress, &checkaddr, sizeof(struct sockaddr_storage));
|
||||
capwap_get_network_socket(&g_wtp.net, &g_wtp.acctrlsock, capwap_get_socket(&g_wtp.net, g_wtp.acctrladdress.ss_family, IPPROTO_UDP, 1));
|
||||
capwap_get_network_socket(&g_wtp.net, &g_wtp.acdatasock, capwap_get_socket(&g_wtp.net, g_wtp.acctrladdress.ss_family, (g_wtp.transport.type == CAPWAP_UDP_TRANSPORT ? IPPROTO_UDP : IPPROTO_UDPLITE), CAPWAP_DATA_SOCKET));
|
||||
break;
|
||||
}
|
||||
if (!capwap_compare_ip(acpreferredaddr, &checkaddr)) {
|
||||
indexpreferred = j;
|
||||
memcpy(&peeraddr, &checkaddr, sizeof(union sockaddr_capwap));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check by number of WTP */
|
||||
if (indexpreferred == -1) {
|
||||
if ((countwtp == -1) || (countwtp > controlipv4->wtpcount)) {
|
||||
countwtp = controlipv4->wtpcount;
|
||||
memcpy(&g_wtp.acctrladdress, &checkaddr, sizeof(struct sockaddr_storage));
|
||||
capwap_get_network_socket(&g_wtp.net, &g_wtp.acctrlsock, capwap_get_socket(&g_wtp.net, g_wtp.acctrladdress.ss_family, IPPROTO_UDP, 1));
|
||||
capwap_get_network_socket(&g_wtp.net, &g_wtp.acdatasock, capwap_get_socket(&g_wtp.net, g_wtp.acctrladdress.ss_family, (g_wtp.transport.type == CAPWAP_UDP_TRANSPORT ? IPPROTO_UDP : IPPROTO_UDPLITE), CAPWAP_DATA_SOCKET));
|
||||
}
|
||||
/* Check by number of WTP */
|
||||
if (indexpreferred == -1) {
|
||||
if ((countwtp == -1) || (countwtp > controlipv4->wtpcount)) {
|
||||
countwtp = controlipv4->wtpcount;
|
||||
memcpy(&peeraddr, &checkaddr, sizeof(union sockaddr_capwap));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* AC with IPv6 */
|
||||
if ((g_wtp.net.sock_family == AF_UNSPEC) || (g_wtp.net.sock_family == AF_INET6)) {
|
||||
if ((g_wtp.net.localaddr.ss.ss_family == AF_INET6)) {
|
||||
for (w = 0; w < response->controlipv6->count; w++) {
|
||||
struct capwap_controlipv6_element* controlipv6 = (struct capwap_controlipv6_element*)capwap_array_get_item_pointer(response->controlipv6, w);
|
||||
|
||||
/* Create IPv6 address */
|
||||
memset(&checkaddr, 0, sizeof(struct sockaddr_storage));
|
||||
checkaddripv6 = (struct sockaddr_in6*)&checkaddr;
|
||||
checkaddripv6->sin6_family = AF_INET6;
|
||||
checkaddripv6->sin6_port = htons(CAPWAP_CONTROL_PORT);
|
||||
memcpy(&checkaddripv6->sin6_addr, &controlipv6->address, sizeof(struct in6_addr));
|
||||
checkaddr.sin6.sin6_family = AF_INET6;
|
||||
memcpy(&checkaddr.sin6.sin6_addr, &controlipv6->address, sizeof(struct in6_addr));
|
||||
checkaddr.sin6.sin6_port = htons(CAPWAP_CONTROL_PORT);
|
||||
|
||||
/* Check for preferred AC */
|
||||
for (j = 0; j < ((indexpreferred != -1) ? indexpreferred : g_wtp.acpreferedarray->count); j++) {
|
||||
struct sockaddr_storage* acpreferredaddr = (struct sockaddr_storage*)capwap_array_get_item_pointer(g_wtp.acpreferedarray, j);
|
||||
union sockaddr_capwap* acpreferredaddr = (union sockaddr_capwap*)capwap_array_get_item_pointer(g_wtp.acpreferedarray, j);
|
||||
|
||||
if (!capwap_compare_ip(acpreferredaddr, &checkaddr)) {
|
||||
indexpreferred = j;
|
||||
memcpy(&g_wtp.acctrladdress, &checkaddr, sizeof(struct sockaddr_storage));
|
||||
capwap_get_network_socket(&g_wtp.net, &g_wtp.acctrlsock, capwap_get_socket(&g_wtp.net, g_wtp.acctrladdress.ss_family, IPPROTO_UDP, 1));
|
||||
capwap_get_network_socket(&g_wtp.net, &g_wtp.acdatasock, capwap_get_socket(&g_wtp.net, g_wtp.acctrladdress.ss_family, (g_wtp.transport.type == CAPWAP_UDP_TRANSPORT ? IPPROTO_UDP : IPPROTO_UDPLITE), CAPWAP_DATA_SOCKET));
|
||||
memcpy(&peeraddr, &checkaddr, sizeof(union sockaddr_capwap));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -106,9 +92,7 @@ void wtp_dfa_state_discovery_timeout(struct capwap_timeout* timeout, unsigned lo
|
||||
if (indexpreferred == -1) {
|
||||
if ((countwtp == -1) || (countwtp > controlipv6->wtpcount)) {
|
||||
countwtp = controlipv6->wtpcount;
|
||||
memcpy(&g_wtp.acctrladdress, &checkaddr, sizeof(struct sockaddr_storage));
|
||||
capwap_get_network_socket(&g_wtp.net, &g_wtp.acctrlsock, capwap_get_socket(&g_wtp.net, g_wtp.acctrladdress.ss_family, IPPROTO_UDP, 1));
|
||||
capwap_get_network_socket(&g_wtp.net, &g_wtp.acdatasock, capwap_get_socket(&g_wtp.net, g_wtp.acctrladdress.ss_family, (g_wtp.transport.type == CAPWAP_UDP_TRANSPORT ? IPPROTO_UDP : IPPROTO_UDPLITE), CAPWAP_DATA_SOCKET));
|
||||
memcpy(&peeraddr, &checkaddr, sizeof(union sockaddr_capwap));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -119,32 +103,24 @@ void wtp_dfa_state_discovery_timeout(struct capwap_timeout* timeout, unsigned lo
|
||||
wtp_free_discovery_response_array();
|
||||
|
||||
/* Change state if found AC */
|
||||
if (g_wtp.acctrladdress.ss_family != AF_UNSPEC) {
|
||||
memcpy(&g_wtp.acdataaddress, &g_wtp.acctrladdress, sizeof(struct sockaddr_storage));
|
||||
CAPWAP_SET_NETWORK_PORT(&g_wtp.acdataaddress, CAPWAP_GET_NETWORK_PORT(&g_wtp.acdataaddress) + 1);
|
||||
if (peeraddr.ss.ss_family != AF_UNSPEC) {
|
||||
union sockaddr_capwap localaddr;
|
||||
|
||||
/* Retrieve local address */
|
||||
if (capwap_get_localaddress_by_remoteaddress(&g_wtp.wtpctrladdress, &g_wtp.acctrladdress, g_wtp.net.bind_interface, (!(g_wtp.net.bind_ctrl_flags & CAPWAP_IPV6ONLY_FLAG) ? 1 : 0))) {
|
||||
struct sockaddr_storage sockinfo;
|
||||
socklen_t sockinfolen = sizeof(struct sockaddr_storage);
|
||||
if (!capwap_network_get_localaddress(&localaddr, &peeraddr, g_wtp.net.bindiface)) {
|
||||
CAPWAP_SET_NETWORK_PORT(&localaddr, CAPWAP_GET_NETWORK_PORT(&g_wtp.net.localaddr));
|
||||
|
||||
memset(&sockinfo, 0, sizeof(struct sockaddr_storage));
|
||||
if (!getsockname(g_wtp.acctrlsock.socket[g_wtp.acctrlsock.type], (struct sockaddr*)&sockinfo, &sockinfolen)) {
|
||||
CAPWAP_SET_NETWORK_PORT(&g_wtp.wtpctrladdress, CAPWAP_GET_NETWORK_PORT(&sockinfo));
|
||||
/* */
|
||||
capwap_crypt_setconnection(&g_wtp.dtls, g_wtp.net.socket, &localaddr, &peeraddr);
|
||||
|
||||
/* */
|
||||
memcpy(&g_wtp.wtpdataaddress, &g_wtp.wtpctrladdress, sizeof(struct sockaddr_storage));
|
||||
CAPWAP_SET_NETWORK_PORT(&g_wtp.wtpdataaddress, CAPWAP_GET_NETWORK_PORT(&g_wtp.wtpdataaddress) + 1);
|
||||
|
||||
/* */
|
||||
if (!g_wtp.enabledtls) {
|
||||
wtp_send_join(); /* Bypass DTLS connection */
|
||||
} else {
|
||||
wtp_start_dtlssetup(); /* Create DTLS connection */
|
||||
}
|
||||
|
||||
return;
|
||||
/* */
|
||||
if (!g_wtp.enabledtls) {
|
||||
wtp_send_join(); /* Bypass DTLS connection */
|
||||
} else {
|
||||
wtp_start_dtlssetup(); /* Create DTLS connection */
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -193,15 +169,8 @@ 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++) {
|
||||
int sock;
|
||||
struct sockaddr_storage* sendtoaddr = (struct sockaddr_storage*)capwap_array_get_item_pointer(g_wtp.acdiscoveryarray, i);
|
||||
|
||||
sock = capwap_get_socket(&g_wtp.net, sendtoaddr->ss_family, IPPROTO_UDP, 1);
|
||||
if (sock >= 0) {
|
||||
if (!capwap_sendto_fragmentpacket(sock, g_wtp.requestfragmentpacket, NULL, sendtoaddr)) {
|
||||
capwap_logging_debug("Warning: error to send discovery request packet");
|
||||
break;
|
||||
}
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
@ -223,7 +192,7 @@ void wtp_dfa_state_discovery(struct capwap_parsed_packet* packet) {
|
||||
|
||||
/* */
|
||||
binding = GET_WBID_HEADER(packet->rxmngpacket->header);
|
||||
if (packet->rxmngpacket->isctrlpacket && (binding == g_wtp.binding) && (packet->rxmngpacket->ctrlmsg.type == CAPWAP_DISCOVERY_RESPONSE) && ((g_wtp.localseqnumber - 1) == packet->rxmngpacket->ctrlmsg.seq)) {
|
||||
if ((binding == g_wtp.binding) && (packet->rxmngpacket->ctrlmsg.type == CAPWAP_DISCOVERY_RESPONSE) && ((g_wtp.localseqnumber - 1) == packet->rxmngpacket->ctrlmsg.seq)) {
|
||||
struct capwap_resultcode_element* resultcode;
|
||||
|
||||
/* Check the success of the Request */
|
||||
|
Reference in New Issue
Block a user