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;
}
/* 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) {
/* Wait receive packet with timeout */
int capwap_wait_recvready(struct pollfd* fds, int fdscount, struct timeout_control* timeout) {
int i;
int polltimeout = -1;
int readysocket;
int result = CAPWAP_RECV_ERROR_SOCKET;
int polltimeout = -1;
ASSERT(fds);
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 */
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 */
for (i = 0; i < fdscount; i++) {
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;
socklen_t sendaddresslen = sizeof(struct sockaddr_storage);
struct sockaddr_storage sockinfo;
@ -358,10 +368,22 @@ int capwap_recvfrom(struct pollfd* fds, int fdscount, void* buffer, int* size, s
struct cmsghdr* cmsg;
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 */
memset(&sockinfo, 0, sizeof(struct sockaddr_storage));
if (getsockname(fds[i].fd, (struct sockaddr*)&sockinfo, &sockinfolen) < 0) {
break;
if (getsockname(fd, (struct sockaddr*)&sockinfo, &sockinfolen) < 0) {
return 0;
}
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 */
do {
packetsize = recvmsg(fds[i].fd, &msgh, 0);
packetsize = recvmsg(fd, &msgh, 0);
} while ((packetsize < 0) && ((errno == EAGAIN) || (errno == EINTR)));
if (packetsize > 0) {
@ -420,30 +442,38 @@ int capwap_recvfrom(struct pollfd* fds, int fdscount, void* buffer, int* size, s
}
}
} else if (packetsize < 0) {
break;
return 0;
}
/* Packet receive */
*size = packetsize;
result = i;
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 1;
}
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);
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_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_ipv4_mapped_ipv6(struct sockaddr_storage* source, struct sockaddr_storage* dest);