00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "helperfsm.h"
00027 #include "helperfsm_private.h"
00028 #include "comm.h"
00029 #include "netio.h"
00030 #include "debug.h"
00031 #include "helpercon.h"
00032 #include <string.h>
00033 #include <unistd.h>
00034
00035 errorcode helper_fsm_start(connlist_t *list, connlist_item_t *item) {
00036
00037
00038 errorcode ret;
00039
00040
00041 CHECK_NOT_NULL(list,ERROR_NULL_ARG_1);
00042 CHECK_NOT_NULL(item,ERROR_NULL_ARG_2);
00043
00044
00045
00046 item->info.port_alloc.method = COMM_PORT_ALLOC_UNKNOWN;
00047 item->info.port_alloc.method_set = FLAG_UNSET;
00048 item->info.port_alloc.ext_port = PORT_UNKNOWN;
00049 item->info.port_alloc.ext_port_set = FLAG_UNSET;
00050 item->info.peer.ip = IP_UNKNOWN;
00051 item->info.peer.port = PORT_UNKNOWN;
00052 item->info.peer.set = FLAG_UNSET;
00053 item->info.buddy.ext_ip = IP_UNKNOWN;
00054 item->info.buddy.ext_port = PORT_UNKNOWN;
00055 item->info.buddy.int_ip = IP_UNKNOWN;
00056 item->info.buddy.int_port = PORT_UNKNOWN;
00057 item->info.buddy.identifier = FLAG_UNSET;
00058 item->info.buddy.ext_port_set = FLAG_UNSET;
00059 item->info.buddy_syn.seq_num = SEQ_NUM_UNKNOWN;
00060 item->info.buddy_syn.seq_num_set = FLAG_UNSET;
00061 item->info.bday.seq_num = SEQ_NUM_UNKNOWN;
00062 item->info.bday.seq_num_set = FLAG_UNSET;
00063 item->info.bday.port = PORT_UNKNOWN;
00064 item->info.bday.port_set = FLAG_UNSET;
00065 item->info.bday.status = FLAG_UNSET;
00066
00067
00068 if(FAILED(connlist_add(list,item))) {
00069
00070 close(item->info.socks.peer);
00071 return ERROR_LIST_ADD;
00072 }
00073
00074 DEBUG(DBG_LIST,"LIST:item Watchers: %d\n",(int)item->watchers);
00075
00076
00077 ret = helper_fsm_hello(list,item);
00078 if (FAILED(ret)) {
00079 if (ret==ERROR_NETWORK_READ){
00080 DEBUG(DBG_PROTOCOL,"PROTOCOL:no hello message\n");
00081 }
00082
00083 close(item->info.socks.peer);
00084
00085 CHECK_FAILED(connlist_forget(list,connlist_item_match,item),
00086 ERROR_LIST_REMOVE_1);
00087 return ERROR_CALLED_FUNCTION;
00088 }
00089
00090
00091 close(item->info.socks.peer);
00092
00093 CHECK_FAILED(connlist_forget(list,connlist_item_match,item),
00094 ERROR_LIST_REMOVE_2);
00095
00096 return SUCCESS;
00097 }
00098
00099 errorcode helper_fsm_hello(connlist_t *list, connlist_item_t *item) {
00100
00101
00102 comm_msg_hello_t hello;
00103
00104
00105 CHECK_NOT_NULL(list,ERROR_NULL_ARG_1);
00106 CHECK_NOT_NULL(item,ERROR_NULL_ARG_2);
00107
00108
00109
00110
00111
00112 CHECK_FAILED(readMsg(item->info.socks.peer, COMM_MSG_HELLO,
00113 &hello, sizeof(hello)), ERROR_NETWORK_READ);
00114
00115 DEBUG(DBG_PROTOCOL,"PROTOCOL:received HELLO\n");
00116
00117
00118 item->info.peer.port = hello.peer_port;
00119 item->info.peer.ip = hello.peer_ip;
00120 item->info.peer.set = FLAG_SET;
00121 item->info.buddy.int_ip = hello.buddy_int_ip;
00122 item->info.buddy.int_port = hello.buddy_int_port;
00123 item->info.buddy.ext_ip = hello.buddy_ext_ip;
00124 item->info.buddy.identifier = FLAG_SET;
00125
00126 DEBUG(DBG_VERBOSE,"VERBOSE:Information from peer hello\n");
00127 DEBUG(DBG_VERBOSE,"VERBOSE:peer.............%s:%u\n",
00128 DBG_IP(item->info.peer.ip),
00129 DBG_PORT(item->info.peer.port));
00130 DEBUG(DBG_VERBOSE,"VERBOSE:buddy internal...%s:%u\n",
00131 DBG_IP(item->info.buddy.int_ip),
00132 DBG_PORT(item->info.buddy.int_port));
00133 DEBUG(DBG_VERBOSE,"VERBOSE:buddy external...%s\n",
00134 DBG_IP(item->info.buddy.ext_ip));
00135
00136
00137 CHECK_FAILED(sendMsg(item->info.socks.peer, COMM_MSG_CONNECT_AGAIN,
00138 NULL, 0),ERROR_NETWORK_SEND);
00139
00140 DEBUG(DBG_PROTOCOL,"PROTOCOL:sent CONNECT_AGAIN\n");
00141
00142
00143 CHECK_FAILED(helper_fsm_conn2(list,item),ERROR_CALLED_FUNCTION);
00144
00145 return SUCCESS;
00146 }
00147
00148
00149 errorcode helper_fsm_conn2(connlist_t *list, connlist_item_t *item) {
00150
00151
00152 observed_data_t find_data;
00153 connlist_item_t *port_pred_item = NULL;
00154 comm_msg_pred_port_t msg;
00155
00156
00157 CHECK_NOT_NULL(list,ERROR_NULL_ARG_1);
00158 CHECK_NOT_NULL(item,ERROR_NULL_ARG_2);
00159
00160
00161
00162 CHECK_FAILED(readMsg(item->info.socks.peer, COMM_MSG_CONNECTED_AGAIN,
00163 NULL,0),ERROR_NETWORK_READ);
00164
00165 DEBUG(DBG_PROTOCOL,"PROTOCOL:CONNECTED_AGAIN\n");
00166
00167
00168
00169 memcpy(&find_data, &item->obs_data, sizeof(observed_data_t));
00170
00171
00172 find_data.port = PORT_ADD(find_data.port,1);
00173
00174
00175
00176
00177
00178 DEBUG((DBG_PORT_PRED|DBG_LIST), "PORT_PRED|LIST:finding 2nd connection entry in list\n");
00179 if (FAILED(find_conn2(list,&find_data,&port_pred_item))) {
00180
00181 DEBUG(DBG_PORT_PRED,"PORT_PRED:couldn't find 2nd connection\n");
00182 msg.port_alloc = COMM_PORT_ALLOC_RAND;
00183
00184 item->info.port_alloc.method = COMM_PORT_ALLOC_RAND;
00185 item->info.port_alloc.method_set = FLAG_SET;
00186
00187 item->info.port_alloc.ext_port = PORT_UNKNOWN;
00188 item->info.port_alloc.ext_port_set = FLAG_SET;
00189 }
00190 else {
00191 DEBUG(DBG_PORT_PRED,"PORT_PRED:found 2nd connection\n");
00192 msg.port_alloc = COMM_PORT_ALLOC_SEQ;
00193
00194 item->info.port_alloc.method = COMM_PORT_ALLOC_SEQ;
00195 item->info.port_alloc.method_set = FLAG_SET;
00196
00197
00198 item->info.port_alloc.ext_port = PORT_ADD(
00199 item->obs_data.port,2);
00200 item->info.port_alloc.ext_port_set = FLAG_SET;
00201
00202
00203 DEBUG(DBG_LIST, "LIST:forgeting about port pred entry\n");
00204 CHECK_FAILED(connlist_forget(list,connlist_item_match,
00205 port_pred_item),ERROR_1);
00206 }
00207
00208 DEBUG(DBG_PORT_PRED, "PORT_PRED:port alloc method is %s\n",
00209 (item->info.port_alloc.method==COMM_PORT_ALLOC_SEQ) ?
00210 "sequential" : "random" );
00211
00212
00213 CHECK_FAILED(sendMsg(item->info.socks.peer, COMM_MSG_PORT_PRED,
00214 &msg,sizeof(msg)),ERROR_NETWORK_SEND);
00215
00216 DEBUG(DBG_PROTOCOL,"PROTOCOL:sent PORT PRED\n");
00217
00218
00219 CHECK_FAILED(helper_fsm_buddy_alloc(list,item),ERROR_CALLED_FUNCTION);
00220
00221 return SUCCESS;
00222 }
00223
00224 errorcode helper_fsm_buddy_alloc(connlist_t *list, connlist_item_t *item) {
00225
00226
00227 connlist_item_t *found_buddy = NULL;
00228 comm_msg_buddy_alloc_t msg;
00229 errorcode ret;
00230
00231
00232 CHECK_NOT_NULL(list,ERROR_NULL_ARG_1);
00233 CHECK_NOT_NULL(item,ERROR_NULL_ARG_2);
00234
00235
00236
00237 ret = SUCCESS;
00238
00239
00240 CHECK_FAILED(readMsg(item->info.socks.peer,
00241 COMM_MSG_WAITING_FOR_BUDDY_ALLOC,NULL,0),ERROR_NETWORK_READ);
00242 DEBUG(DBG_PROTOCOL,"PROTOCOL:received WAITING_FOR_BUDDY_ALLOC\n");
00243
00244
00245
00246 if (FAILED(get_buddy(list,item,&found_buddy))){
00247 DEBUG(DBG_BUDDY,"BUDDY:couldn't find buddy\n");
00248 return ERROR_1;
00249 }
00250
00251 DEBUG(DBG_BUDDY,"BUDDY:found buddy\n");
00252
00253
00254
00255 if (FAILED(wait_for_buddy_port_alloc(&(found_buddy->info)))){
00256 ret = ERROR_1;
00257 goto forget_and_return;
00258 }
00259
00260 msg.buddy_port_alloc = found_buddy->info.port_alloc.method;
00261 if ( (found_buddy->info.port_alloc.method == COMM_PORT_ALLOC_RAND) &&
00262 (item->info.port_alloc.method == COMM_PORT_ALLOC_RAND) )
00263 msg.support = COMM_CONNECTION_UNSUPPORTED;
00264 else
00265 msg.support = COMM_CONNECTION_SUPPORTED;
00266
00267
00268 if (FAILED(sendMsg(item->info.socks.peer,COMM_MSG_BUDDY_ALLOC,
00269 &msg,sizeof(comm_msg_buddy_alloc_t)))) {
00270 ret = ERROR_NETWORK_SEND;
00271 DEBUG(DBG_PROTOCOL,
00272 "fsm_buddy_alloc:PROTOCOL:sent BUDDY_ALLOC\n");
00273 goto forget_and_return;
00274 }
00275
00276 if (msg.support == COMM_CONNECTION_UNSUPPORTED) {
00277 DEBUG(DBG_VERBOSE, "VERBOSE:connection unsupported!\n");
00278 ret = ERROR_2;
00279 goto forget_and_return;
00280 }
00281
00282
00283
00284 if (FAILED(helper_fsm_buddy_port(list,item,found_buddy))) {
00285 ret = ERROR_CALLED_FUNCTION;
00286 goto forget_and_return;
00287 }
00288
00289 forget_and_return:
00290
00291 DEBUG(DBG_LIST, "LIST:forgeting about buddy entry\n");
00292 CHECK_FAILED(connlist_forget(list,connlist_item_match,found_buddy),
00293 ERROR_3);
00294 return ret;
00295 }
00296
00297 errorcode helper_fsm_buddy_port(connlist_t *list, connlist_item_t *peer,
00298 connlist_item_t *buddy) {
00299
00300 comm_msg_buddy_port_t msg;
00301
00302
00303 CHECK_NOT_NULL(list,ERROR_NULL_ARG_1);
00304 CHECK_NOT_NULL(peer,ERROR_NULL_ARG_2);
00305 CHECK_NOT_NULL(buddy,ERROR_NULL_ARG_3);
00306
00307
00308
00309
00310 CHECK_FAILED(readMsg(peer->info.socks.peer,
00311 COMM_MSG_WAITING_FOR_BUDDY_PORT,NULL,0),ERROR_NETWORK_READ);
00312 DEBUG(DBG_PROTOCOL,"PROTOCOL:received WAITING_FOR_BUDDY_PORT\n");
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322 CHECK_FAILED(wait_for_buddy_port_known(&(buddy->info)),ERROR_1);
00323
00324 msg.ext_port = buddy->info.port_alloc.ext_port;
00325 msg.bday = ( ( (peer->info.port_alloc.method == COMM_PORT_ALLOC_RAND)
00326 || (buddy->info.port_alloc.method == COMM_PORT_ALLOC_RAND))
00327 ? COMM_BDAY_NEEDED
00328 : COMM_BDAY_NOT_NEEDED
00329 );
00330
00331
00332 CHECK_FAILED(sendMsg(peer->info.socks.peer,COMM_MSG_BUDDY_PORT,
00333 &msg,sizeof(msg)),ERROR_NETWORK_SEND);
00334 DEBUG(DBG_PROTOCOL,"PROTOCOL:sent BUDDY_PORT\n");
00335
00336
00337 if (peer->info.port_alloc.method==COMM_PORT_ALLOC_RAND) {
00338
00339 CHECK_FAILED(helper_fsm_start_peer_bday(list,peer,buddy),
00340 ERROR_CALLED_FUNCTION_1);
00341 }
00342 else if (buddy->info.port_alloc.method==COMM_PORT_ALLOC_RAND) {
00343
00344
00345 CHECK_FAILED(helper_fsm_start_buddy_bday(list,peer,buddy),
00346 ERROR_CALLED_FUNCTION_2);
00347 }
00348 else {
00349
00350 CHECK_FAILED(helper_fsm_start_direct_conn(list,peer,buddy),
00351 ERROR_CALLED_FUNCTION_3);
00352 }
00353
00354
00355
00356
00357
00358
00359 return SUCCESS;
00360 }
00361
00362
00363
00364 errorcode helper_fsm_start_direct_conn(connlist_t *list, connlist_item_t *peer,
00365 connlist_item_t *buddy) {
00366
00367
00368 comm_msg_buddy_syn_seq_t buddy_syn_msg;
00369 comm_msg_peer_syn_seq_t peer_syn_msg;
00370
00371
00372 CHECK_NOT_NULL(list,ERROR_NULL_ARG_1);
00373 CHECK_NOT_NULL(peer,ERROR_NULL_ARG_2);
00374 CHECK_NOT_NULL(buddy,ERROR_NULL_ARG_3);
00375
00376
00377
00378
00379 CHECK_FAILED(readMsg(peer->info.socks.peer,COMM_MSG_BUDDY_SYN_SEQ,
00380 &buddy_syn_msg,sizeof(buddy_syn_msg)),ERROR_NETWORK_READ);
00381 DEBUG(DBG_PROTOCOL,"PROTOCOL:received BUDDY_SYN_SEQ\n");
00382 DEBUG(DBG_VERBOSE,"VERBOSE:sequence number is %u\n",
00383 DBG_SEQ_NUM(buddy_syn_msg.seq_num));
00384
00385
00386 peer->info.buddy_syn.seq_num = buddy_syn_msg.seq_num;
00387 peer->info.buddy_syn.seq_num_set = FLAG_SET;
00388
00389
00390
00391 CHECK_FAILED(wait_for_buddy_syn_seq_num(&(buddy->info)),ERROR_1);
00392 peer_syn_msg.seq_num = buddy->info.buddy_syn.seq_num;
00393
00394
00395 CHECK_FAILED(sendMsg(peer->info.socks.peer,COMM_MSG_PEER_SYN_SEQ,
00396 &peer_syn_msg,sizeof(peer_syn_msg)),ERROR_NETWORK_SEND);
00397 DEBUG(DBG_PROTOCOL,"PROTOCOL:sent PEER_SYN_SEQ\n");
00398
00399
00400 CHECK_FAILED(helper_fsm_goodbye(list,peer,buddy),
00401 ERROR_CALLED_FUNCTION);
00402
00403 return SUCCESS;
00404 }
00405
00406 errorcode helper_fsm_goodbye(connlist_t *list, connlist_item_t *peer,
00407 connlist_item_t *buddy) {
00408
00409
00410 comm_msg_goodbye_t goodbye;
00411
00412
00413 CHECK_NOT_NULL(list,ERROR_NULL_ARG_1);
00414 CHECK_NOT_NULL(peer,ERROR_NULL_ARG_2);
00415 CHECK_NOT_NULL(buddy,ERROR_NULL_ARG_2);
00416
00417
00418
00419
00420 CHECK_FAILED(readMsg(peer->info.socks.peer,COMM_MSG_GOODBYE, &goodbye,
00421 sizeof(goodbye)),ERROR_NETWORK_READ);
00422
00423 DEBUG(DBG_PROTOCOL,"PROTOCOL:received GOODBYE\n");
00424
00425 DEBUG(DBG_VERBOSE,"VERBOSE:peer's connection was %sa success!\n",
00426 ((goodbye.success_or_failure==FLAG_FAILED) ? "not ": ""));
00427
00428 return SUCCESS;
00429 }
00430
00431 errorcode helper_fsm_start_peer_bday(connlist_t *list, connlist_item_t *peer,
00432 connlist_item_t *buddy) {
00433
00434
00435 comm_msg_syn_flooded_t msg;
00436
00437
00438 CHECK_NOT_NULL(list,ERROR_NULL_ARG_1);
00439 CHECK_NOT_NULL(peer,ERROR_NULL_ARG_2);
00440 CHECK_NOT_NULL(buddy,ERROR_NULL_ARG_3);
00441
00442
00443
00444
00445 CHECK_FAILED(readMsg(peer->info.socks.peer,COMM_MSG_SYN_FLOODED,
00446 &msg,sizeof(msg)),ERROR_NETWORK_READ);
00447 DEBUG(DBG_PROTOCOL,"PROTOCOL:received SYN_FLOODED\n");
00448
00449
00450 peer->info.bday.seq_num = msg.seq_num;
00451 peer->info.bday.seq_num_set = FLAG_SET;
00452
00453
00454
00455 CHECK_FAILED(sendMsg(peer->info.socks.peer,
00456 COMM_MSG_BUDDY_SYN_ACK_FLOODED,NULL,0),ERROR_NETWORK_SEND);
00457
00458
00459 CHECK_FAILED(helper_fsm_end_peer_bday(list,peer,buddy),
00460 ERROR_CALLED_FUNCTION);
00461
00462 return ERROR_1;
00463 }
00464
00465 errorcode helper_fsm_end_peer_bday(connlist_t *list, connlist_item_t *peer,
00466 connlist_item_t *buddy) {
00467
00468
00469 comm_msg_bday_success_port_t receive_msg;
00470 comm_msg_buddy_port_t send_msg;
00471
00472
00473 CHECK_NOT_NULL(list,ERROR_NULL_ARG_1);
00474 CHECK_NOT_NULL(peer,ERROR_NULL_ARG_2);
00475 CHECK_NOT_NULL(buddy,ERROR_NULL_ARG_3);
00476
00477
00478
00479 if (FAILED(readMsg(peer->info.socks.peer,COMM_MSG_BDAY_SUCCESS_PORT,
00480 &receive_msg,sizeof(receive_msg)))) {
00481 peer->info.bday.status = FLAG_FAILED;
00482 return ERROR_NETWORK_READ;
00483 }
00484
00485
00486 peer->info.bday.port = receive_msg.port;
00487 peer->info.bday.port_set = FLAG_SET;
00488 peer->info.bday.status = FLAG_SUCCESS;
00489
00490
00491
00492 peer->info.port_alloc.ext_port = receive_msg.port;
00493 peer->info.port_alloc.ext_port_set = FLAG_SET;
00494
00495
00496
00497
00498 send_msg.ext_port = buddy->info.port_alloc.ext_port;
00499 send_msg.bday = COMM_BDAY_NOT_NEEDED;
00500
00501 CHECK_FAILED(sendMsg(peer->info.socks.peer,COMM_MSG_BUDDY_PORT,
00502 &send_msg,sizeof(send_msg)),ERROR_NETWORK_SEND);
00503 DEBUG(DBG_PROTOCOL,"PROTOCOL:sent BUDDY_PORT...again\n");
00504
00505
00506
00507 CHECK_FAILED(helper_fsm_start_direct_conn(list,peer,buddy),
00508 ERROR_CALLED_FUNCTION);
00509
00510 return SUCCESS;
00511
00512 }
00513
00514 errorcode helper_fsm_start_buddy_bday(connlist_t *list, connlist_item_t *peer,
00515 connlist_item_t *buddy) {
00516
00517
00518 comm_msg_syn_ack_flood_seq_num_t msg;
00519
00520
00521 CHECK_NOT_NULL(list,ERROR_NULL_ARG_1);
00522 CHECK_NOT_NULL(peer,ERROR_NULL_ARG_2);
00523 CHECK_NOT_NULL(buddy,ERROR_NULL_ARG_3);
00524
00525
00526
00527 CHECK_FAILED(readMsg(peer->info.socks.peer,
00528 COMM_MSG_WAITING_TO_SYN_ACK_FLOOD,NULL,0),ERROR_NETWORK_READ);
00529 DEBUG(DBG_PROTOCOL,"PROTOCOL:received WAITING_TO_SYN_ACK_FLOOD\n");
00530
00531
00532
00533 CHECK_FAILED(wait_for_buddy_syn_flood(&buddy->info),ERROR_1);
00534
00535
00536 msg.seq_num = buddy->info.bday.seq_num;
00537
00538 CHECK_FAILED(sendMsg(peer->info.socks.peer,
00539 COMM_MSG_SYN_ACK_FLOOD_SEQ_NUM,&msg,sizeof(msg)),
00540 ERROR_NETWORK_SEND);
00541 DEBUG(DBG_PROTOCOL,"PROTOCOL:sent SYN_ACK_FLOOD_SEQ_NUM\n");
00542
00543
00544 CHECK_FAILED(helper_fsm_end_buddy_bday(list,peer,buddy),
00545 ERROR_CALLED_FUNCTION);
00546
00547 return ERROR_1;
00548 }
00549
00550 errorcode helper_fsm_end_buddy_bday(connlist_t *list, connlist_item_t *peer,
00551 connlist_item_t *buddy) {
00552
00553
00554 comm_msg_buddy_port_t msg;
00555
00556
00557 CHECK_NOT_NULL(list,ERROR_NULL_ARG_1);
00558 CHECK_NOT_NULL(peer,ERROR_NULL_ARG_2);
00559 CHECK_NOT_NULL(buddy,ERROR_NULL_ARG_3);
00560
00561
00562
00563
00564 CHECK_FAILED(readMsg(peer->info.socks.peer,COMM_MSG_SYN_ACK_FLOOD_DONE,
00565 NULL,0),ERROR_NETWORK_READ);
00566 DEBUG(DBG_PROTOCOL,"PROTOCOL:received SYN_ACK_FLOOD_DONE\n");
00567
00568
00569 CHECK_FAILED(wait_for_buddy_bday_port(&(buddy->info)),ERROR_1);
00570
00571
00572
00573
00574 msg.ext_port = buddy->info.bday.port;
00575 msg.bday = COMM_BDAY_NOT_NEEDED;
00576
00577
00578 CHECK_FAILED(sendMsg(peer->info.socks.peer,COMM_MSG_BUDDY_PORT,
00579 &msg,sizeof(msg)),ERROR_NETWORK_SEND);
00580 DEBUG(DBG_PROTOCOL,"PROTOCOL:sent BUDDY_PORT...again\n");
00581
00582
00583
00584 CHECK_FAILED(helper_fsm_start_direct_conn(list,peer,buddy),
00585 ERROR_CALLED_FUNCTION);
00586
00587 return SUCCESS;
00588
00589 }
00590