forked from qpzm0192/Remote-Procedure-Call
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbinder.cpp
More file actions
482 lines (390 loc) · 18.1 KB
/
Copy pathbinder.cpp
File metadata and controls
482 lines (390 loc) · 18.1 KB
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
#include <stdio.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
#include <iostream>
#include <sys/socket.h>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <sys/select.h>
#include <sstream>
#include <stdlib.h>
#include <limits.h>
#include <vector>
#include <map>
#include <deque>
using namespace std;
#define ARG_CHAR 1
#define ARG_SHORT 2
#define ARG_INT 3
#define ARG_LONG 4
#define ARG_DOUBLE 5
#define ARG_FLOAT 6
#define ARG_INPUT 31
#define ARG_OUTPUT 30
#define REGISTER "REGISTER"
#define REGISTER_SUCCESS "REGISTER_SUCCESS"
#define REGISTER_FAILURE "REGISTER_FAILURE"
#define LOC_REQUEST "LOC_REQUEST"
#define LOC_SUCCESS "LOC_SUCCESS"
#define LOC_FAILURE "LOC_FAILURE"
#define EXECUTE "EXECUTE"
#define EXECUTE_SUCCESS "EXECUTE_SUCCESS"
#define EXECUTE_FAILURE "EXECUTE_FAILURE"
#define TERMINATE "TERMINATE"
// warning code
#define NORMAL "00"
#define OVERWRITE "01"
#define DUP_REGISTRATION "02"
// error code
#define NOT_EXIST "-2"
void rm_array_length(char * arg_type){
//unsigned char *arg_type_us = (unsigned char *) arg_type;
//unsigned char newb[4];
//newb[0] = arg_type_us[0]; //0-7
//newb[1] = arg_type_us[1]; //7-15
((unsigned char *)arg_type)[2] = (0 >> 8) & 0xFF;
((unsigned char *)arg_type)[3] = 1 & 0xFF;
}
int find_server(deque<pair <string, int> > RR_Queue, string sidwPort){
int result = -1;
for(int i = 0; i < RR_Queue.size(); i++){
if(RR_Queue[i].first.compare(sidwPort) == 0)
result = RR_Queue[i].second;
}
return result;
}
void conToByte(int i, unsigned char* bytes) {
bytes[0] = (i >> 24); //high
bytes[1] = (i >> 16); //
bytes[2] = (i >> 8); //
bytes[3] = i; //low
}
/*void conToByte(int i, char* bytes) {
unsigned char * new_bytes = (unsigned char *) bytes;
new_bytes[0] = (i >> 24); //high
new_bytes[1] = (i >> 16); //
new_bytes[2] = (i >> 8); //
new_bytes[3] = i; //low
bytes = (char*) new_bytes;
}*/
int conToInt(char * bytes) {
unsigned char * new_bytes = (unsigned char *) bytes;
int Int32 = 0;
Int32 = (Int32 << 8) + new_bytes[0];
Int32 = (Int32 << 8) + new_bytes[1];
Int32 = (Int32 << 8) + new_bytes[2];
Int32 = (Int32 << 8) + new_bytes[3];
return Int32;
}
string append_length(string msg){
string result;
unsigned char byte[4];
conToByte(msg.length(), byte);
string hex_len(reinterpret_cast<char*>(byte), 4);
result.append(hex_len);
result.append(msg);
cout << "append_length: " << msg << endl;
return msg;
}
int main () {
fd_set master; // master file descriptor list
fd_set read_fds; // temp file descriptor list for select()
int fdmax; // maximum file descriptor number
//int listener; // listening socket descriptor
int newfd; // newly accept()ed socket descriptor
struct sockaddr_storage remoteaddr; // client address
socklen_t addrlen;
char buf[USHRT_MAX]; // buffer for client data
int nbytes;
// get host name, get machine name
char hostname[USHRT_MAX];
//hostname[1023] = "0/";
gethostname(hostname, USHRT_MAX-1);
//cout << hostname << endl;
printf("BINDER_ADDRESS %s\n", hostname);
// create socket
struct hostent *hp;
struct sockaddr_in mysockaddr;
int mysocket, accept_socket;
hp = gethostbyname(hostname);
mysockaddr.sin_family= hp->h_addrtype;
// initial portnum as 0
unsigned short portnum = 0;
mysockaddr.sin_port= htons(portnum);
mysocket= socket(AF_INET, SOCK_STREAM, 0);
// bind
bind(mysocket,(struct sockaddr *)&mysockaddr,sizeof(struct sockaddr_in));
// listen
listen(mysocket, 50);
socklen_t sockaddrlen = sizeof(struct sockaddr_in);
getsockname(mysocket, (struct sockaddr *)&mysockaddr, &sockaddrlen);
// print port num
cout << "BINDER_PORT " << mysockaddr.sin_port << endl;
// my registration data structure
char buf_type[16];
char buf_type_length[4];
char buf_sid[65535];
char buf_sid_length[4];
char buf_port[65535];
char buf_port_length[4];
char buf_name[65535];
char buf_name_length[4];
char buf_arg_type[65535];
char buf_arg_type_length[4];
// procedure signature:
// name, argTypes
// location:
// server_indentifier, port
// mymap:
// <signature, location> where signature is
// name, num, type1, type2, type3... ***without saying of array length**
// my pair:
// <server id, port>
// vector of maps
deque<pair <string, int> > RR_Queue;
vector< map<string,pair<string, string> > >VoMap;
FD_ZERO(&master); // clear the master and temp sets
FD_ZERO(&read_fds);
int fd_count = 0;
bool cangoin = true;
bool firstTime = true;
// add the listener to the master set
FD_SET(mysocket, &master);
// keep track of the biggest file descriptor
fdmax = mysocket; // so far, it's this one
// main loop
while(true) {
read_fds = master; // copy it
if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) {
perror("select");
//exit(4);
}
// run through the existing connections looking for data to read
for(int i = 0; i <= fdmax; i++) {
if (FD_ISSET(i, &read_fds)) { // we got one!!
if (i == mysocket && cangoin) {
// handle new connections
addrlen = sizeof remoteaddr;
newfd = accept(mysocket, (struct sockaddr *)&mysockaddr, &sockaddrlen);
if (newfd == -1) {
perror("accept");
} else {
FD_SET(newfd, &master); // add to master set
if (newfd > fdmax) { // keep track of the max
fdmax = newfd;
}
//printf("selectserver: new connection from sth on "
// "socket %d\n", newfd);
}
}
else {
// handle data from a client
if(fd_count == 0 && !firstTime)
return 0;
else if((nbytes = read(i, buf_type_length,4)) <= 0){
if (nbytes == 0) {
// connection closed
//printf("select server: socket %d hung up\n", i);
} else {
//perror("recv");
//cout << "lol" << endl;
}
//cout << "================================================" << endl;
fd_count--;
close(i); // bye!
FD_CLR(i, &master); // remove from master set
}
else{
////cout << "length is " << conToInt(buf_type_length) << endl;
read(i, buf_type, conToInt(buf_type_length));
buf_type[conToInt(buf_type_length)] = 0;
// we got some data from a client
string buf_str(buf_type);
////cout << "socket is " << i <<endl;
if(buf_str.compare(REGISTER)==0){
// receive
//cout << "got REGISTER" << endl;
read(i, buf_sid_length,4);
read(i, buf_sid, conToInt(buf_sid_length));
buf_sid[conToInt(buf_sid_length)] = 0;
//cout << "got sid: " << buf_sid << endl;
read(i, buf_port_length,4);
read(i, buf_port, conToInt(buf_port_length));
buf_port[conToInt(buf_port_length)] = 0;
//cout << "got port: " << buf_port << endl;
read(i, buf_name_length,4);
read(i, buf_name, conToInt(buf_name_length));
buf_name[conToInt(buf_name_length)] = 0;
//cout << "got name: " << buf_name << endl;
read(i, buf_arg_type_length,4);
string str_name(buf_name);
for(int j = 0; j < conToInt(buf_arg_type_length); j++){
char buf_arg_type[4];
read(i, buf_arg_type, 4);
rm_array_length(buf_arg_type);
string str_arg_type(buf_arg_type);
str_name.append(str_arg_type);
int myint = conToInt(buf_arg_type);
////cout << "got arg type " << j << " " << myint << endl;
}
// insert
pair<string, string> temp_pair(buf_sid, buf_port);
string str_sid(buf_sid);
string str_port(buf_port);
string str_warning(NORMAL);
int index = find_server(RR_Queue, str_sid.append(str_port));
if(index == -1){
//cout << "first time found server" << endl;
map<string,pair<string, string> > thisMap;
thisMap[str_name] = temp_pair;
int size = VoMap.size();
VoMap.push_back(thisMap);
pair <string, int> mypair(str_sid, size);
RR_Queue.push_back(mypair);
firstTime = false;
fd_count++;
}
else{
//cout << "insert into exist server map" << endl;
if (VoMap[index][str_name].first.compare(temp_pair.first) == 0 &&
VoMap[index][str_name].second.compare(temp_pair.second) == 0){
str_warning = OVERWRITE;
}
VoMap[index][str_name] = temp_pair;
}
string str_reply(REGISTER_SUCCESS);
str_reply.append(str_warning);
// display current map
//cout << "****************MyMap*******************" << endl;
for(int j = 0; j < VoMap.size(); j++){
//cout << " server " << j << endl;
map<string,pair<string, string> > mymap = VoMap[j];
for (map<string,pair<string, string> >::iterator it = mymap.begin(); it != mymap.end(); ++it) {
//cout << it->first << ": " << it->second.first << ", " << it->second.second << endl;
}
}
//cout << "****************************************" << endl;
// read null terminator
read(i, buf_name, 1024);
// send reply
send(i, str_reply.c_str(), str_reply.length(), 0);
}
else if(buf_str.compare(LOC_REQUEST)==0){
//cout << "got LOC_REQUEST" << endl;
read(i, buf_name_length,4);
read(i, buf_name, conToInt(buf_name_length));
buf_name[conToInt(buf_name_length)] = 0;
//cout << "got func name: " << buf_name << endl;
read(i, buf_arg_type_length,4);
string str_name(buf_name);
for(int j = 0; j < conToInt(buf_arg_type_length); j++){
char buf_arg_type[4];
read(i, buf_arg_type, 4);
rm_array_length(buf_arg_type);
string str_arg_type(buf_arg_type);
str_name.append(str_arg_type);
int myint = conToInt(buf_arg_type);
}
// fetch
string sid;
string port;
for(int j = 0; j < RR_Queue.size(); j++){
pair <string, int> mypair = RR_Queue.front();
int index = mypair.second;
RR_Queue.pop_front();
RR_Queue.push_back(mypair);
map<string,pair<string, string> >::iterator it = VoMap[index].find(str_name);
if (it != VoMap[index].end()){ // if found
sid = VoMap[index][str_name].first;
port = VoMap[index][str_name].second;
break;
}
}
// send reply
string str_reply;
if(!sid.length() && !port.length()){
// set reply type
string str_type(LOC_FAILURE);
unsigned char byte[4];
conToByte(strlen(LOC_FAILURE), byte);
string hex_len(reinterpret_cast<char*>(byte), 4);
string str_err(NOT_EXIST);
str_reply.append(hex_len);
str_reply.append(str_type);
str_reply.append(str_err);
}
else{
// set reply type
string str_type(LOC_SUCCESS);
unsigned char byte[4];
conToByte(strlen(LOC_SUCCESS), byte);
string hex_len(reinterpret_cast<char*>(byte), 4);
str_reply.append(hex_len);
str_reply.append(str_type);
// sid
unsigned char byte_sid[4];
conToByte(sid.length(), byte_sid);
string hex_len_sid(reinterpret_cast<char*>(byte_sid), 4);
str_reply.append(hex_len_sid);
str_reply.append(sid);
// port
unsigned char byte_port[4];
conToByte(port.length(), byte_port);
string hex_len_post(reinterpret_cast<char*>(byte_port), 4);
str_reply.append(hex_len_post);
str_reply.append(port);
}
// read null terminator
read(i, buf_name, 1024);
send(i, str_reply.c_str(), str_reply.length(), 0);
}
else if(buf_str.compare(TERMINATE)==0){
//cout << "got TERMINATE" << endl;
// set reply type
string str_reply;
string str_type(TERMINATE);
unsigned char byte[4];
conToByte(strlen(TERMINATE), byte);
string hex_len(reinterpret_cast<char*>(byte), 4);
str_reply.append(hex_len);
str_reply.append(str_type);
cangoin = false;
for( int fd = 0; fd < fdmax; fd++ ){
if ( FD_ISSET(fd, &master) && fd != mysocket ){
if (send(fd, str_reply.c_str(), str_reply.length(), 0) < 0){
//cout << "send terminate failed" << endl;
}
}
}
}
else{
//cout << "unknown type, got: <" << buf_str << ">" << endl;
}
// clean read buffer
//if (recv(i, buf_type, sizeof buf_type, 0) < 0)
// //cout << "recv failed" << endl;
////cout << "recv done" << endl;
////cout << "send done" << endl;
// clean buffer
memset(buf_type, 0, sizeof buf_type);
memset(buf_type_length, 0, sizeof buf_type_length);
memset(buf_sid, 0, sizeof buf_sid);
memset(buf_sid_length, 0, sizeof buf_sid_length);
memset(buf_port, 0, sizeof buf_port);
memset(buf_port_length, 0, sizeof buf_port_length);
memset(buf_name, 0, sizeof buf_name);
memset(buf_name_length, 0, sizeof buf_name_length);
memset(buf_arg_type, 0, sizeof buf_arg_type);
memset(buf_arg_type_length, 0, sizeof buf_arg_type_length);
//cout << endl;
//sleep(1);
}
} // END handle data from client
} // END got new incoming connection
} // END looping through file descriptors
}
}