Fix error management to send socket functions

This commit is contained in:
vemax78 2014-12-27 18:45:09 +01:00
parent 98069694c5
commit 2894b2c7aa
4 changed files with 80 additions and 14 deletions

View File

@ -61,27 +61,23 @@ static struct nl_sock* nl_create_handle(struct nl_cb* cb) {
/* */
static int ac_kmod_no_seq_check(struct nl_msg* msg, void* arg) {
capwap_logging_debug("Call ac_kmod_no_seq_check");
return NL_OK;
}
/* */
static int ac_kmod_error_handler(struct sockaddr_nl* nla, struct nlmsgerr* err, void* arg) {
capwap_logging_debug("Call ac_kmod_error_handler %d", err->error);
*((int*)arg) = err->error;
return NL_STOP;
}
/* */
static int ac_kmod_finish_handler(struct nl_msg* msg, void* arg) {
capwap_logging_debug("Call ac_kmod_finish_handler");
*((int*)arg) = 0;
return NL_SKIP;
}
/* */
static int ac_kmod_ack_handler(struct nl_msg* msg, void* arg) {
capwap_logging_debug("Call ac_kmod_ack_handler");
*((int*)arg) = 0;
return NL_STOP;
}

View File

@ -56,6 +56,7 @@ static int capwap_bio_method_recv(CYASSL* ssl, char* buffer, int length, void* c
/* */
static int capwap_bio_method_send(CYASSL* ssl, char* buffer, int length, void* context) {
int err;
char data[CAPWAP_MAX_PACKET_SIZE];
struct capwap_dtls* dtls = (struct capwap_dtls*)context;
struct capwap_dtls_header* dtlspreamble = (struct capwap_dtls_header*)data;
@ -72,7 +73,9 @@ static int capwap_bio_method_send(CYASSL* ssl, char* buffer, int length, void* c
memcpy(&data[0] + sizeof(struct capwap_dtls_header), buffer, length);
/* Send packet */
if (capwap_sendto(dtls->sock, data, length + sizeof(struct capwap_dtls_header), &dtls->peeraddr) <= 0) {
err = capwap_sendto(dtls->sock, data, length + sizeof(struct capwap_dtls_header), &dtls->peeraddr);
if (err <= 0) {
capwap_logging_warning("Unable to send crypt packet, sentto return error %d", err);
return CYASSL_CBIO_ERR_GENERAL;
}
@ -485,18 +488,25 @@ void capwap_crypt_freesession(struct capwap_dtls* dtls) {
/* */
int capwap_crypt_sendto(struct capwap_dtls* dtls, void* buffer, int size) {
int err;
ASSERT(dtls != NULL);
ASSERT(dtls->sock >= 0);
ASSERT(buffer != NULL);
ASSERT(size > 0);
if (!dtls->enable) {
return capwap_sendto(dtls->sock, buffer, size, &dtls->peeraddr);
err = capwap_sendto(dtls->sock, buffer, size, &dtls->peeraddr);
if (err <= 0) {
capwap_logging_warning("Unable to send plain packet, sentto return error %d", err);
}
return err;
}
/* Valid DTLS status */
if (dtls->action != CAPWAP_DTLS_ACTION_DATA) {
return 0;
return -ENOTCONN;
}
return CyaSSL_write((CYASSL*)dtls->sslsession, buffer, size);
@ -504,19 +514,28 @@ int capwap_crypt_sendto(struct capwap_dtls* dtls, void* buffer, int size) {
/* */
int capwap_crypt_sendto_fragmentpacket(struct capwap_dtls* dtls, struct capwap_list* fragmentlist) {
int err;
struct capwap_list_item* item;
ASSERT(dtls != NULL);
ASSERT(dtls->sock >= 0);
ASSERT(fragmentlist != NULL);
/* */
if (!dtls->enable) {
return capwap_sendto_fragmentpacket(dtls->sock, fragmentlist, &dtls->peeraddr);
}
/* */
item = fragmentlist->first;
while (item) {
struct capwap_fragment_packet_item* fragmentpacket = (struct capwap_fragment_packet_item*)item->item;
ASSERT(fragmentpacket != NULL);
ASSERT(fragmentpacket->offset > 0);
if (!capwap_crypt_sendto(dtls, fragmentpacket->buffer, fragmentpacket->offset)) {
err = capwap_crypt_sendto(dtls, fragmentpacket->buffer, fragmentpacket->offset);
if (err <= 0) {
capwap_logging_warning("Unable to send crypt fragment, sentto return error %d", err);
return 0;
}

View File

@ -4,6 +4,7 @@
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <net/if_arp.h>
#include <arpa/inet.h>
#include <ifaddrs.h>
/* */
@ -288,13 +289,17 @@ int capwap_recvfrom(int sock, void* buffer, int* size, union sockaddr_capwap* fr
while (result <= 0) {
result = recvmsg(sock, &msgh, 0);
if ((result <= 0) && (errno != EAGAIN) && (errno != EINTR)) {
capwap_logging_warning("Unable to recv packet, recvmsg return %d with error %d", result, errno);
return -1;
}
}
/* Check if IPv4 is mapped into IPv6 */
if (fromaddr->ss.ss_family == AF_INET6) {
capwap_ipv4_mapped_ipv6(fromaddr);
if (!capwap_ipv4_mapped_ipv6(fromaddr)) {
capwap_logging_warning("Receive packet with invalid fromaddr");
return -1;
}
}
/* */
@ -320,6 +325,7 @@ int capwap_recvfrom(int sock, void* buffer, int* size, union sockaddr_capwap* fr
/* Check if IPv4 is mapped into IPv6 */
if (fromaddr->ss.ss_family == AF_INET) {
if (!capwap_ipv4_mapped_ipv6(toaddr)) {
capwap_logging_warning("Receive packet with invalid toaddr");
return -1;
}
}
@ -331,6 +337,15 @@ int capwap_recvfrom(int sock, void* buffer, int* size, union sockaddr_capwap* fr
/* Packet receive */
*size = result;
#ifdef DEBUG
{
char strfromaddr[INET6_ADDRSTRLEN];
char strtoaddr[INET6_ADDRSTRLEN];
capwap_logging_debug("Receive packet from %s to %s with size %d", capwap_address_to_string(fromaddr, strfromaddr, INET6_ADDRSTRLEN), capwap_address_to_string(toaddr, strtoaddr, INET6_ADDRSTRLEN), result);
}
#endif
return 0;
}
@ -367,25 +382,37 @@ int capwap_network_set_pollfd(struct capwap_network* net, struct pollfd* fds, in
/* */
int capwap_sendto(int sock, void* buffer, int size, union sockaddr_capwap* toaddr) {
int result = 0;
int result;
ASSERT(sock >= 0);
ASSERT(buffer != NULL);
ASSERT(size > 0);
ASSERT(toaddr != NULL);
while (result <= 0) {
do {
result = sendto(sock, buffer, size, 0, &toaddr->sa, sizeof(union sockaddr_capwap));
if ((result <= 0) && (errno != EAGAIN) && (errno != EINTR)) {
return -1;
if ((result < 0) && (errno != EAGAIN) && (errno != EINTR)) {
capwap_logging_warning("Unable to send packet, sendto return %d with error %d", result, errno);
return -errno;
} else if ((result > 0) && (result != size)) {
capwap_logging_warning("Unable to send packet, mismatch sendto size %d - %d", size, result);
return -ENETRESET;
}
} while (result < 0);
#ifdef DEBUG
{
char strtoaddr[INET6_ADDRSTRLEN];
capwap_logging_debug("Sent packet to %s with result %d", capwap_address_to_string(toaddr, strtoaddr, INET6_ADDRSTRLEN), result);
}
#endif
return result;
}
/* */
int capwap_sendto_fragmentpacket(int sock, struct capwap_list* fragmentlist, union sockaddr_capwap* toaddr) {
int err;
struct capwap_list_item* item;
ASSERT(sock >= 0);
@ -398,7 +425,9 @@ int capwap_sendto_fragmentpacket(int sock, struct capwap_list* fragmentlist, uni
ASSERT(fragmentpacket != NULL);
ASSERT(fragmentpacket->offset > 0);
if (!capwap_sendto(sock, fragmentpacket->buffer, fragmentpacket->offset, toaddr)) {
err = capwap_sendto(sock, fragmentpacket->buffer, fragmentpacket->offset, toaddr);
if (err <= 0) {
capwap_logging_warning("Unable to send fragment, sentto return error %d", err);
return 0;
}
@ -481,6 +510,27 @@ int capwap_address_from_string(const char* ip, union sockaddr_capwap* sockaddr)
return 1;
}
/* Convert address to string */
const char* capwap_address_to_string(union sockaddr_capwap* sockaddr, char* ip, int len) {
ASSERT(sockaddr != NULL);
ASSERT(ip != NULL);
ASSERT(len > 0);
if ((sockaddr->ss.ss_family == AF_INET) && (len >= INET_ADDRSTRLEN)) {
if (!inet_ntop(AF_INET, &sockaddr->sin.sin_addr, ip, len)) {
*ip = 0;
}
} else if ((sockaddr->ss.ss_family == AF_INET6) && (len >= INET6_ADDRSTRLEN)) {
if (!inet_ntop(AF_INET6, &sockaddr->sin6.sin6_addr, ip, len)) {
*ip = 0;
}
} else {
*ip = 0;
}
return ip;
}
/* Get macaddress from interface */
int capwap_get_macaddress_from_interface(const char* interface, char* macaddress) {
int sock;

View File

@ -68,6 +68,7 @@ int capwap_wait_recvready(struct pollfd* fds, int fdscount, struct capwap_timeou
int capwap_recvfrom(int sock, void* buffer, int* size, union sockaddr_capwap* fromaddr, union sockaddr_capwap* toaddr);
int capwap_address_from_string(const char* ip, union sockaddr_capwap* sockaddr);
const char* capwap_address_to_string(union sockaddr_capwap* sockaddr, char* ip, int len);
char* capwap_printf_macaddress(char* buffer, const uint8_t* macaddress, int type);
int capwap_scanf_macaddress(uint8_t* macaddress, const char* buffer, int type);