net_send
发送数据函数
int net_send(int sockfd, struct timeval timeout, char *mem, unsigned int len) {
unsigned int byte_count = 0;
int n;
使用 poll 函数检测 pfd 上的事件,关心的是 POLLOUT
事件也就是数据可写的事件,超时时间为 1ms:
struct pollfd pfd[1];
pfd[0].fd = sockfd;
pfd[0].events = POLLOUT;
int rv = poll(pfd, 1, 1);
设置超时,这里的 timeout 在 send_over_network|fuzz 中是 1ms。
setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout));
如果存在可写事件且可写事件为 POLLOUT
时,向目标发送数据。
if (rv > 0) {
if (pfd[0].revents & POLLOUT) {
while (byte_count < len) {
usleep(10);
n = send(sockfd, &mem[byte_count], len - byte_count, MSG_NOSIGNAL);
if (n == 0) return byte_count;
if (n == -1) return -1;
byte_count += n;
}
}
}
return byte_count;
}
net_recv
接收数据函数
int net_recv(int sockfd, struct timeval timeout, int poll_w, char **response_buf, unsigned int *len) {
char temp_buf[1000];
int n;
struct pollfd pfd[1];
pfd[0].fd = sockfd;
pfd[0].events = POLLIN;
int rv = poll(pfd, 1, poll_w);
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
// data received
if (rv > 0) {
if (pfd[0].revents & POLLIN) {
n = recv(sockfd, temp_buf, sizeof(temp_buf), 0);
if ((n < 0) && (errno != EAGAIN)) {
return 1;
}
while (n > 0) {
usleep(10);
*response_buf = (unsigned char *)ck_realloc(*response_buf, *len + n + 1);
memcpy(&(*response_buf)[*len], temp_buf, n);
(*response_buf)[(*len) + n] = '\0';
*len = *len + n;
n = recv(sockfd, temp_buf, sizeof(temp_buf), 0);
if ((n < 0) && (errno != EAGAIN)) {
return 1;
}
}
}
} else
if (rv < 0) // an error was returned
return 1;
// rv == 0 poll timeout or all data pending after poll has been received successfully
return 0;
}