int loop int tunfd int sockfd if EXIT_FAILURE startUpdateTimestamp Thr

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
int loop(int tunfd, int sockfd)
{
if (EXIT_FAILURE == startUpdateTimestampThread())
{
return EXIT_FAILURE;
}
struct pollfd allFDs[4] = { { tunfd, POLLIN, 0 }, { sockfd, POLLIN, 0 }, { tunfd, POLLOUT, 0 }, { sockfd, POLLOUT, 0 } };
struct pollfd* readFDs = &allFDs[0];
struct pollfd* readTunFDs = &readFDs[0];
struct pollfd* readSockFDs = &readFDs[1];
struct pollfd* writeFDs = &allFDs[2];
struct pollfd* writeTunFDs = &writeFDs[0];
struct pollfd* writeSockFDs = &writeFDs[1];
#define CAN_READ_TUN (readFDs[0].revents & POLLIN)
#define CAN_READ_SOCK (readFDs[1].revents & POLLIN)
#define CAN_WRITE_TUN (writeFDs[0].revents & POLLOUT)
#define CAN_WRITE_SOCK (writeFDs[1].revents & POLLOUT)
#define SHOULD_CONTINUE (!shouldStop && !errored && !stopped && running)
while (SHOULD_CONTINUE)
{
int code = poll(readFDs, 2, 1000);
if (code < 0)
{
LOG_ERROR("%s", strerror(errno));
}
HANDLE_POLL_ERROR(code);
if (shouldSendHeartbeat())
{
code = poll(writeSockFDs, 1, 100);
HANDLE_POLL_ERROR(code);
if (code > 0)
{
RETURN_IF_FAILS(sendHeartbeat(sockfd));
}
if (code <= 0)
{
continue;
}
}
do
{
if (CAN_READ_SOCK && CAN_READ_TUN)
{
code = poll(writeFDs, 2, 200);
}
else if (CAN_READ_SOCK)
{
code = poll(writeTunFDs, 1, 100);
}
else if (CAN_READ_TUN)
{
code = poll(writeSockFDs, 1, 100);
}
else
{
break;
}
HANDLE_POLL_ERROR(code);
if (code <= 0)
{
if (!CAN_READ_TUN)
{
code = poll(readTunFDs, 1, 0);
}
else if (!CAN_READ_SOCK)
{
code = poll(readSockFDs, 1, 0);
}
HANDLE_POLL_ERROR(code);
continue;
}
if (CAN_READ_TUN && CAN_WRITE_SOCK)
{
RETURN_IF_FAILS(tunnelToSocket(tunfd, sockfd));
}
if (CAN_READ_SOCK && CAN_WRITE_TUN)
{
RETURN_IF_FAILS(socketToTunnel(sockfd, tunfd));
}
break;
}
while (SHOULD_CONTINUE);
}
return errored ? EXIT_FAILURE : EXIT_SUCCESS;
}