-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsend_recv_rpc_data.c
129 lines (117 loc) · 3.67 KB
/
send_recv_rpc_data.c
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#include <stdio.h>
#include <pthread.h>
#include <stdint.h>
#include <endian.h>
#include "send_recv_rpc_data.h"
#define MAX_DATA2_LEN 100000
/* receive rpc_data through socket, return NULL if fails, return rpc_data* if success*/
rpc_data* recv_rpc_data(int sockfd_comm){
//receive flag, if -1, quit directly
int32_t flag, flag_nbo;
if(recv(sockfd_comm, &flag_nbo, sizeof(flag_nbo), 0) <=0){
perror("recv rpc_data flag");
return NULL;
}
flag = ntohl(flag_nbo);
if(flag == -1){
perror("recv rpc_data invalid flag, early exit");
return NULL;
}
//receive data 1
int64_t data1, data1_nbo;
if(recv(sockfd_comm, &data1_nbo, sizeof(data1_nbo), 0) <= 0){
perror("recv rpc_data data1");
return NULL;
}
data1 = be64toh(data1_nbo);
//receive data 2 len
uint32_t data2_len_nbo;
size_t data2_len;
if(recv(sockfd_comm, &data2_len_nbo, sizeof(data2_len_nbo), 0) <= 0){
perror("recv rpc_data data2_len");
return NULL;
}
data2_len = (size_t)(ntohl(data2_len_nbo));
//receive data2 only if data2_len is greater than 0
void* data2 = NULL;
if(data2_len > 0){
data2 = malloc(data2_len);
if(recv(sockfd_comm, data2, data2_len, 0) <= 0){
free(data2);
perror("recv rpc_data data2");
return NULL;
}
}
//construct rpc_data
rpc_data* recv_data = (rpc_data*)malloc(sizeof(*recv_data));
if(recv_data == NULL){
perror("can't allocate recv_data\n");
return NULL;
}
recv_data->data1 = data1;
recv_data->data2_len = data2_len;
recv_data->data2 = data2;
return recv_data;
}
/* send rpc_data through socket, return -1 if fails, return 0 if success */
int send_rpc_data(int sockfd_comm, rpc_data* send_data){
// verify the integrity of rpc_data, and send flag
int32_t flag = 0;
if(send_data == NULL
|| (send_data->data2_len < 0)
|| (send_data->data2_len >= MAX_DATA2_LEN)
|| (send_data->data2_len > 0 && send_data->data2 == NULL)
|| (send_data->data2_len == 0 && send_data->data2 != NULL)
){
flag = -1;
}
int32_t flag_nbo = htonl(flag);
if(send(sockfd_comm, &flag_nbo, sizeof(flag_nbo), 0) <= 0){
perror("send rpc_data flag");
return -1;
}
// based on the verification, report error then quit, or quit directly
// if rpc_data is NULL, quit directly
if(send_data == NULL){
perror("send rpc_data null rpc_data");
return -1;
}
//if data2 overflow, report error to stderr then quit
if(send_data->data2_len >= MAX_DATA2_LEN){
fprintf(stderr, "Overlength error\n");
return -1;
}
// if other error, quit
if(flag == -1){
perror("invalid rpc_data, early exit");
return -1;
}
//send data1
int64_t data1_nbo = htobe64(send_data->data1);
if(send(sockfd_comm, &data1_nbo, sizeof(data1_nbo), 0) <= 0){
perror("send rpc_data data1");
return -1;
}
//send data2 len
uint32_t data2_len_nbo;
data2_len_nbo = htonl(send_data->data2_len);
if(send(sockfd_comm, &data2_len_nbo, sizeof(data2_len_nbo), 0) <= 0){
perror("send rpc_data data2_len");
return -1;
}
//send data2 only if data2_len is greater than 0
if(send_data->data2_len > 0){
if(send(sockfd_comm, send_data->data2, send_data->data2_len, 0) <= 0){
perror("send rpc_data data2");
return -1;
}
}
return 0;
}