mirror of
https://github.com/ntop/n2n.git
synced 2024-09-19 16:41:11 +02:00
Provide better details when sendto_fd fails (#981)
* Refactor traceEvent to allow variable log levels * Refactor sendto failed for less repetition * Refactor sendto_fd to make control flow clearer, also reduce repetition * Tie size to the actual object not its class * Show destination that had issues when sendto_fd fails * Fix MSVC compile - it doesnt support the same variadic macros as gcc
This commit is contained in:
parent
f3e305b254
commit
009311d016
|
@ -168,11 +168,11 @@
|
||||||
#include "tf.h"
|
#include "tf.h"
|
||||||
|
|
||||||
#ifndef TRACE_ERROR
|
#ifndef TRACE_ERROR
|
||||||
#define TRACE_ERROR 0, __FILE__, __LINE__
|
#define TRACE_ERROR 0
|
||||||
#define TRACE_WARNING 1, __FILE__, __LINE__
|
#define TRACE_WARNING 1
|
||||||
#define TRACE_NORMAL 2, __FILE__, __LINE__
|
#define TRACE_NORMAL 2
|
||||||
#define TRACE_INFO 3, __FILE__, __LINE__
|
#define TRACE_INFO 3
|
||||||
#define TRACE_DEBUG 4, __FILE__, __LINE__
|
#define TRACE_DEBUG 4
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ************************************** */
|
/* ************************************** */
|
||||||
|
@ -194,7 +194,8 @@ void setUseSyslog (int use_syslog);
|
||||||
void setTraceFile (FILE *f);
|
void setTraceFile (FILE *f);
|
||||||
int getTraceLevel ();
|
int getTraceLevel ();
|
||||||
void closeTraceFile ();
|
void closeTraceFile ();
|
||||||
void traceEvent (int eventTraceLevel, char* file, int line, char * format, ...);
|
void _traceEvent (int eventTraceLevel, char* file, int line, char * format, ...);
|
||||||
|
#define traceEvent(level, format, ...) _traceEvent(level, __FILE__, __LINE__, format, ##__VA_ARGS__)
|
||||||
|
|
||||||
/* Tuntap API */
|
/* Tuntap API */
|
||||||
int tuntap_open (struct tuntap_dev *device, char *dev, const char *address_mode, char *device_ip,
|
int tuntap_open (struct tuntap_dev *device, char *dev, const char *address_mode, char *device_ip,
|
||||||
|
|
|
@ -1005,13 +1005,12 @@ static void check_known_peer_sock_change (n2n_edge_t *eee,
|
||||||
|
|
||||||
/* ************************************** */
|
/* ************************************** */
|
||||||
|
|
||||||
/** Send a datagram to a socket file descriptor */
|
/*
|
||||||
static ssize_t sendto_fd (n2n_edge_t *eee, const void *buf,
|
* Confirm that we can send to this edge.
|
||||||
size_t len, struct sockaddr_in *dest) {
|
* TODO: for the TCP case, this could cause a stall in the packet
|
||||||
|
* send path, so this probably should be reworked to use a queue
|
||||||
ssize_t sent = 0;
|
*/
|
||||||
int rc = 1;
|
static int check_sock_ready (n2n_edge_t *eee) {
|
||||||
|
|
||||||
// if required (tcp), wait until writeable as soket is set to O_NONBLOCK, could require
|
// if required (tcp), wait until writeable as soket is set to O_NONBLOCK, could require
|
||||||
// some wait time directly after re-opening
|
// some wait time directly after re-opening
|
||||||
if(eee->conf.connect_tcp) {
|
if(eee->conf.connect_tcp) {
|
||||||
|
@ -1022,46 +1021,54 @@ static ssize_t sendto_fd (n2n_edge_t *eee, const void *buf,
|
||||||
FD_SET(eee->sock, &socket_mask);
|
FD_SET(eee->sock, &socket_mask);
|
||||||
wait_time.tv_sec = 0;
|
wait_time.tv_sec = 0;
|
||||||
wait_time.tv_usec = 500000;
|
wait_time.tv_usec = 500000;
|
||||||
rc = select(eee->sock + 1, NULL, &socket_mask, NULL, &wait_time);
|
return select(eee->sock + 1, NULL, &socket_mask, NULL, &wait_time);
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(rc > 0) {
|
/** Send a datagram to a socket file descriptor */
|
||||||
|
static ssize_t sendto_fd (n2n_edge_t *eee, const void *buf,
|
||||||
|
size_t len, struct sockaddr_in *dest,
|
||||||
|
const n2n_sock_t * n2ndest) {
|
||||||
|
|
||||||
|
ssize_t sent = 0;
|
||||||
|
|
||||||
|
if(check_sock_ready(eee) > 0) {
|
||||||
|
|
||||||
sent = sendto(eee->sock, buf, len, 0 /*flags*/,
|
sent = sendto(eee->sock, buf, len, 0 /*flags*/,
|
||||||
(struct sockaddr *)dest, sizeof(struct sockaddr_in));
|
(struct sockaddr *)dest, sizeof(*dest));
|
||||||
|
|
||||||
if((sent <= 0) && (errno)) {
|
if(sent > 0) {
|
||||||
|
traceEvent(TRACE_DEBUG, "sent=%d to ", (signed int)sent);
|
||||||
|
return sent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(errno) {
|
||||||
char * c = strerror(errno);
|
char * c = strerror(errno);
|
||||||
|
n2n_sock_str_t sockbuf;
|
||||||
|
|
||||||
|
int level = TRACE_WARNING;
|
||||||
// downgrade to TRACE_DEBUG in case of custom AF_INVALID, i.e. supernode not resolved yet
|
// downgrade to TRACE_DEBUG in case of custom AF_INVALID, i.e. supernode not resolved yet
|
||||||
if(errno == EAFNOSUPPORT /* 93 */) {
|
if(errno == EAFNOSUPPORT /* 93 */) {
|
||||||
traceEvent(TRACE_DEBUG, "sendto failed (%d) %s", errno, c);
|
level = TRACE_DEBUG;
|
||||||
#ifdef WIN32
|
|
||||||
traceEvent(TRACE_DEBUG, "WSAGetLastError(): %u", WSAGetLastError());
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
traceEvent(TRACE_WARNING, "sendto failed (%d) %s", errno, c);
|
|
||||||
#ifdef WIN32
|
|
||||||
traceEvent(TRACE_WARNING, "WSAGetLastError(): %u", WSAGetLastError());
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(eee->conf.connect_tcp) {
|
traceEvent(level, "sendto(%s) failed (%d) %s",
|
||||||
|
sock_to_cstr(sockbuf, n2ndest),
|
||||||
|
errno, c);
|
||||||
|
#ifdef WIN32
|
||||||
|
traceEvent(level, "WSAGetLastError(): %u", WSAGetLastError());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we reach here, either because !check_sock_ready() or (errno) */
|
||||||
supernode_disconnect(eee);
|
supernode_disconnect(eee);
|
||||||
eee->sn_wait = 1;
|
eee->sn_wait = 1;
|
||||||
traceEvent(TRACE_DEBUG, "disconnected supernode due to sendto() error");
|
traceEvent(TRACE_DEBUG, "disconnected supernode due to error while sendto_fd");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
traceEvent(TRACE_DEBUG, "sent=%d to ", (signed int)sent);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
supernode_disconnect(eee);
|
|
||||||
eee->sn_wait = 1;
|
|
||||||
traceEvent(TRACE_DEBUG, "disconnected supernode due to select() timeout");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return sent;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Send a datagram to a socket defined by a n2n_sock_t */
|
/** Send a datagram to a socket defined by a n2n_sock_t */
|
||||||
|
@ -1094,13 +1101,13 @@ static ssize_t sendto_sock (n2n_edge_t *eee, const void * buf,
|
||||||
|
|
||||||
// prepend packet length...
|
// prepend packet length...
|
||||||
uint16_t pktsize16 = htobe16(len);
|
uint16_t pktsize16 = htobe16(len);
|
||||||
sent = sendto_fd(eee, (uint8_t*)&pktsize16, sizeof(pktsize16), &peer_addr);
|
sent = sendto_fd(eee, (uint8_t*)&pktsize16, sizeof(pktsize16), &peer_addr, dest);
|
||||||
|
|
||||||
if(sent <= 0)
|
if(sent <= 0)
|
||||||
return -1;
|
return -1;
|
||||||
// ...before sending the actual data
|
// ...before sending the actual data
|
||||||
}
|
}
|
||||||
sent = sendto_fd(eee, buf, len, &peer_addr);
|
sent = sendto_fd(eee, buf, len, &peer_addr, dest);
|
||||||
|
|
||||||
// if the connection is tcp, i.e. not the regular sock...
|
// if the connection is tcp, i.e. not the regular sock...
|
||||||
if(eee->conf.connect_tcp) {
|
if(eee->conf.connect_tcp) {
|
||||||
|
|
|
@ -99,7 +99,7 @@ void closeTraceFile () {
|
||||||
}
|
}
|
||||||
|
|
||||||
#define N2N_TRACE_DATESIZE 32
|
#define N2N_TRACE_DATESIZE 32
|
||||||
void traceEvent (int eventTraceLevel, char* file, int line, char * format, ...) {
|
void _traceEvent (int eventTraceLevel, char* file, int line, char * format, ...) {
|
||||||
|
|
||||||
va_list va_ap;
|
va_list va_ap;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user