Divided the logic of the capwap_recvfrom function into two distinct functions:

poll (capwap_wait_recvready) and recv (capwap_recvfrom_fd)
This commit is contained in:
vemax78 2013-11-02 19:08:05 +01:00
parent 769d0f414e
commit 6ee885f9b6
2 changed files with 157 additions and 125 deletions

View File

@ -308,25 +308,14 @@ int capwap_compare_ip(struct sockaddr_storage* addr1, struct sockaddr_storage* a
return 1; return 1;
} }
/* Receive packet with timeout */ /* Wait receive packet with timeout */
int capwap_recvfrom(struct pollfd* fds, int fdscount, void* buffer, int* size, struct sockaddr_storage* recvfromaddr, struct sockaddr_storage* recvtoaddr, struct timeout_control* timeout) { int capwap_wait_recvready(struct pollfd* fds, int fdscount, struct timeout_control* timeout) {
int i; int i;
int polltimeout = -1;
int readysocket; int readysocket;
int result = CAPWAP_RECV_ERROR_SOCKET; int polltimeout = -1;
ASSERT(fds); ASSERT(fds);
ASSERT(fdscount > 0); ASSERT(fdscount > 0);
ASSERT(buffer != NULL);
ASSERT(size != NULL);
ASSERT(*size > 0);
ASSERT(recvfromaddr != NULL);
ASSERT(recvtoaddr != NULL);
memset(recvfromaddr, 0, sizeof(struct sockaddr_storage));
if (recvtoaddr) {
memset(recvtoaddr, 0, sizeof(struct sockaddr_storage));
}
/* Check timeout */ /* Check timeout */
if (timeout) { if (timeout) {
@ -349,6 +338,27 @@ int capwap_recvfrom(struct pollfd* fds, int fdscount, void* buffer, int* size, s
/* Get packet from only one socket */ /* Get packet from only one socket */
for (i = 0; i < fdscount; i++) { for (i = 0; i < fdscount; i++) {
if ((fds[i].revents & POLLIN) != 0) { if ((fds[i].revents & POLLIN) != 0) {
return i;
} else if ((fds[i].revents & (POLLHUP | POLLERR | POLLNVAL)) != 0) {
return CAPWAP_RECV_ERROR_SOCKET;
}
}
} else if (readysocket == 0) {
/* Update timer for detect timeout */
if (timeout) {
capwap_update_timeout(timeout);
}
return CAPWAP_RECV_ERROR_TIMEOUT;
} else if (errno == EINTR) {
return CAPWAP_RECV_ERROR_INTR;
}
return CAPWAP_RECV_ERROR_SOCKET;
}
/* Receive packet from fd */
int capwap_recvfrom_fd(int fd, void* buffer, int* size, struct sockaddr_storage* recvfromaddr, struct sockaddr_storage* recvtoaddr) {
int packetsize = -1; int packetsize = -1;
socklen_t sendaddresslen = sizeof(struct sockaddr_storage); socklen_t sendaddresslen = sizeof(struct sockaddr_storage);
struct sockaddr_storage sockinfo; struct sockaddr_storage sockinfo;
@ -358,10 +368,22 @@ int capwap_recvfrom(struct pollfd* fds, int fdscount, void* buffer, int* size, s
struct cmsghdr* cmsg; struct cmsghdr* cmsg;
char cbuf[256]; char cbuf[256];
ASSERT(fd >= 0);
ASSERT(buffer != NULL);
ASSERT(size != NULL);
ASSERT(*size > 0);
ASSERT(recvfromaddr != NULL);
ASSERT(recvtoaddr != NULL);
memset(recvfromaddr, 0, sizeof(struct sockaddr_storage));
if (recvtoaddr) {
memset(recvtoaddr, 0, sizeof(struct sockaddr_storage));
}
/* Information socket */ /* Information socket */
memset(&sockinfo, 0, sizeof(struct sockaddr_storage)); memset(&sockinfo, 0, sizeof(struct sockaddr_storage));
if (getsockname(fds[i].fd, (struct sockaddr*)&sockinfo, &sockinfolen) < 0) { if (getsockname(fd, (struct sockaddr*)&sockinfo, &sockinfolen) < 0) {
break; return 0;
} }
iov.iov_base = buffer; iov.iov_base = buffer;
@ -378,7 +400,7 @@ int capwap_recvfrom(struct pollfd* fds, int fdscount, void* buffer, int* size, s
/* Receive packet with recvmsg */ /* Receive packet with recvmsg */
do { do {
packetsize = recvmsg(fds[i].fd, &msgh, 0); packetsize = recvmsg(fd, &msgh, 0);
} while ((packetsize < 0) && ((errno == EAGAIN) || (errno == EINTR))); } while ((packetsize < 0) && ((errno == EAGAIN) || (errno == EINTR)));
if (packetsize > 0) { if (packetsize > 0) {
@ -420,30 +442,38 @@ int capwap_recvfrom(struct pollfd* fds, int fdscount, void* buffer, int* size, s
} }
} }
} else if (packetsize < 0) { } else if (packetsize < 0) {
break; return 0;
} }
/* Packet receive */
*size = packetsize; *size = packetsize;
result = i; return 1;
break;
} else if ((fds[i].revents & (POLLHUP | POLLERR | POLLNVAL)) != 0) {
break;
}
}
} else if (readysocket == 0) {
result = CAPWAP_RECV_ERROR_TIMEOUT;
if (timeout) {
/* Update timer for detect timeout */
capwap_update_timeout(timeout);
}
} else {
if (errno == EINTR) {
result = CAPWAP_RECV_ERROR_INTR;
}
} }
return result; /* Receive packet with timeout */
int capwap_recvfrom(struct pollfd* fds, int fdscount, void* buffer, int* size, struct sockaddr_storage* recvfromaddr, struct sockaddr_storage* recvtoaddr, struct timeout_control* timeout) {
int index;
ASSERT(fds);
ASSERT(fdscount > 0);
ASSERT(buffer != NULL);
ASSERT(size != NULL);
ASSERT(*size > 0);
ASSERT(recvfromaddr != NULL);
ASSERT(recvtoaddr != NULL);
/* Wait packet */
index = capwap_wait_recvready(fds, fdscount, timeout);
if (index < 0) {
return index;
}
/* Receive packet */
if (!capwap_recvfrom_fd(fds[index].fd, buffer, size, recvfromaddr, recvtoaddr)) {
return CAPWAP_RECV_ERROR_SOCKET;
}
return index;
} }
/* */ /* */
@ -1143,7 +1173,6 @@ static short capwap_get_interface_flags(char* iface) {
} }
close(sock); close(sock);
return req.ifr_flags; return req.ifr_flags;
} }

View File

@ -85,6 +85,9 @@ int capwap_compare_ip(struct sockaddr_storage* addr1, struct sockaddr_storage* a
int capwap_sendto(int sock, void* buffer, int size, struct sockaddr_storage* sendfromaddr, struct sockaddr_storage* sendtoaddr); int capwap_sendto(int sock, void* buffer, int size, struct sockaddr_storage* sendfromaddr, struct sockaddr_storage* sendtoaddr);
int capwap_sendto_fragmentpacket(int sock, struct capwap_list* fragmentlist, struct sockaddr_storage* sendfromaddr, struct sockaddr_storage* sendtoaddr); int capwap_sendto_fragmentpacket(int sock, struct capwap_list* fragmentlist, struct sockaddr_storage* sendfromaddr, struct sockaddr_storage* sendtoaddr);
int capwap_wait_recvready(struct pollfd* fds, int fdscount, struct timeout_control* timeout);
int capwap_recvfrom_fd(int fd, void* buffer, int* size, struct sockaddr_storage* recvfromaddr, struct sockaddr_storage* recvtoaddr);
int capwap_recvfrom(struct pollfd* fds, int fdscount, void* buffer, int* size, struct sockaddr_storage* recvfromaddr, struct sockaddr_storage* recvtoaddr, struct timeout_control* timeout); int capwap_recvfrom(struct pollfd* fds, int fdscount, void* buffer, int* size, struct sockaddr_storage* recvfromaddr, struct sockaddr_storage* recvtoaddr, struct timeout_control* timeout);
int capwap_ipv4_mapped_ipv6(struct sockaddr_storage* source, struct sockaddr_storage* dest); int capwap_ipv4_mapped_ipv6(struct sockaddr_storage* source, struct sockaddr_storage* dest);