Main Page | Data Structures | File List | Data Fields | Globals | Related Pages

helperfsm.c

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * Copyright 2005 Daniel Ferullo                                             *
00003  *                                                                           *
00004  * Licensed under the Apache License, Version 2.0 (the "License");           *
00005  * you may not use this file except in compliance with the License.          *
00006  * You may obtain a copy of the License at                                   *
00007  *                                                                           *
00008  *    http://www.apache.org/licenses/LICENSE-2.0                             *
00009  *                                                                           *
00010  * Unless required by applicable law or agreed to in writing, software       *
00011  * distributed under the License is distributed on an "AS IS" BASIS,         *
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  *
00013  * See the License for the specific language governing permissions and       *
00014  * limitations under the License.                                            *
00015  *                                                                           *
00016  *****************************************************************************/
00017 
00018 /**
00019  * @file helperfsm.c
00020  * @author Daniel Ferullo (ferullo@cmu.edu)
00021  *
00022  * @brief contains defintions of fsm-like functions to control helper connection
00023  *        protocol control flow.
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         /* declare variables */
00038         errorcode ret;
00039 
00040         /* error check arguments */
00041         CHECK_NOT_NULL(list,ERROR_NULL_ARG_1);
00042         CHECK_NOT_NULL(item,ERROR_NULL_ARG_2);
00043 
00044         /* do function */
00045         /* set initial values */
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         /* add info to the list */
00068         if(FAILED(connlist_add(list,item))) {
00069                 /* close the socket */
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         /* call next state */
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                 /* close the socket */
00083                 close(item->info.socks.peer);
00084                 /* if the state fails, remove the list item */
00085                 CHECK_FAILED(connlist_forget(list,connlist_item_match,item),
00086                         ERROR_LIST_REMOVE_1);
00087                 return ERROR_CALLED_FUNCTION;
00088         }
00089 
00090         /* close the socket */
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         /* declare variables */
00102         comm_msg_hello_t hello;
00103 
00104         /* error check arguments */
00105         CHECK_NOT_NULL(list,ERROR_NULL_ARG_1);
00106         CHECK_NOT_NULL(item,ERROR_NULL_ARG_2);
00107 
00108         /* do function */
00109         /* this is a strange case, but it is OK if no acceptable message
00110          * is received on this read.  It was probably a port prediction
00111          * second connection */
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         /* save out info from the message */
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         /* send the next message */
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         /* go to next state */
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         /* declare local variables */
00152         observed_data_t find_data;
00153         connlist_item_t *port_pred_item = NULL;
00154         comm_msg_pred_port_t msg;
00155 
00156         /* error check arguments */
00157         CHECK_NOT_NULL(list,ERROR_NULL_ARG_1);
00158         CHECK_NOT_NULL(item,ERROR_NULL_ARG_2);
00159 
00160         /* do function */
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         /* look for info about this second connection in the list */
00168         /* copy of the observed data */
00169         memcpy(&find_data, &item->obs_data, sizeof(observed_data_t));
00170         /* and expect the port prediction port to be on the next sequential
00171          * port */
00172         find_data.port = PORT_ADD(find_data.port,1);
00173 
00174         /* wait 2 seconds, to give the second connection time to add
00175          * it's item to the list (this is instead of having a timeout, in
00176          * essence always wait the full timeout) */
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                 /* set the allocation method */
00184                 item->info.port_alloc.method       = COMM_PORT_ALLOC_RAND;
00185                 item->info.port_alloc.method_set   = FLAG_SET;
00186                 /* set the external port definitively to unknown */
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                 /* set the port allocation method */
00194                 item->info.port_alloc.method     = COMM_PORT_ALLOC_SEQ;
00195                 item->info.port_alloc.method_set = FLAG_SET;
00196                 /* set the predicted port to 2 higher than the port for this
00197                  * connection */
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                 /* forget about the port prediction second connection */
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         /* tell the peer the port allocation method */
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         /* enter next state */
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         /* declare variables */
00227         connlist_item_t *found_buddy = NULL;
00228         comm_msg_buddy_alloc_t msg;
00229         errorcode ret;
00230 
00231         /* error check arguments */
00232         CHECK_NOT_NULL(list,ERROR_NULL_ARG_1);
00233         CHECK_NOT_NULL(item,ERROR_NULL_ARG_2);
00234 
00235         /* do function */
00236 
00237         ret = SUCCESS;
00238 
00239         /* receive the waiting message */
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         /* get pointer to buddy's info*/
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         /* check to make sure all buddy's info has been filled in,
00253          * then fill in the message */
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         /* send out message*/
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         /* enter next state */
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         /* forget the buddy's info */
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         /* declare variables */
00300         comm_msg_buddy_port_t msg;
00301 
00302         /* error check arguments */
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         /* do function */
00308 
00309         /* get message from peer */
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         /* as soon as the buddy's port is known send it to the peer and attach
00315          * a note indicating if the peer should do the birthday paradox so it's
00316          * port can be detected (the peer should be able to determine on it's
00317          * own if this is needed because the helper already told the peer the
00318          * peer's port allocation method, so this is for sanity checking only)
00319          */
00320 
00321         /* wait for the buddy's port */
00322         CHECK_FAILED(wait_for_buddy_port_known(&(buddy->info)),ERROR_1);
00323         /* fill in the message */
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         /* send the message */
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         /* enter next state - it depends on port allocation method */
00337         if (peer->info.port_alloc.method==COMM_PORT_ALLOC_RAND) {
00338                 /* this connections peer is random */
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                 /* the buddy connection is random, the peer is going to
00344                  * need to help find a port */
00345                 CHECK_FAILED(helper_fsm_start_buddy_bday(list,peer,buddy),
00346                         ERROR_CALLED_FUNCTION_2);
00347         }
00348         else {
00349                 /* neither peer is random, go ahead with connection */
00350                 CHECK_FAILED(helper_fsm_start_direct_conn(list,peer,buddy),
00351                         ERROR_CALLED_FUNCTION_3);
00352         }
00353         /**
00354          * there is no check to make sure both peers aren't random, it is assumed
00355          * that this case is handled in an earlier state (since it is
00356          * unsupported).
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         /* declare local variables */
00368         comm_msg_buddy_syn_seq_t buddy_syn_msg;
00369         comm_msg_peer_syn_seq_t peer_syn_msg;
00370 
00371         /* error check arguments */
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         /* do function */
00377 
00378         /* get message from peer with buddy seq num */
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         /* fill in the information about this syn sequence number */
00386         peer->info.buddy_syn.seq_num     = buddy_syn_msg.seq_num;
00387         peer->info.buddy_syn.seq_num_set = FLAG_SET;
00388 
00389         /* make payload to send in next message. first wait for the seq num
00390          * and then fill it in the payload */
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         /* send the message */
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         /* enter next state */
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         /* declare local variables */
00410         comm_msg_goodbye_t goodbye;
00411 
00412         /* error check arguments */
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         /* do function */
00418 
00419         /* receive the message */
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         /* declare local variables */
00435         comm_msg_syn_flooded_t msg;
00436 
00437         /* error check arguments */
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         /* do function */
00443 
00444         /* receive message indicating that the flood happened */
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         /* set the value for the sequence number in the peer's info */
00450         peer->info.bday.seq_num = msg.seq_num;
00451         peer->info.bday.seq_num_set = FLAG_SET;
00452 
00453         /* send message indicating the buddy is about to commence sending the
00454          * SYN/ACKs */
00455         CHECK_FAILED(sendMsg(peer->info.socks.peer,
00456                 COMM_MSG_BUDDY_SYN_ACK_FLOODED,NULL,0),ERROR_NETWORK_SEND);
00457 
00458         /* enter next state */
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         /* declare local variables */
00469         comm_msg_bday_success_port_t receive_msg;
00470         comm_msg_buddy_port_t send_msg;
00471 
00472         /* error check arguments */
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         /* do function */
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         /* set the port value */
00486         peer->info.bday.port               = receive_msg.port;
00487         peer->info.bday.port_set           = FLAG_SET;
00488         peer->info.bday.status             = FLAG_SUCCESS;
00489         /* this location for the external port is no longer valid, since the
00490          * flag was already set, but I set it here just in case I screwed up
00491          * somewhere else in the code and look at it */
00492         peer->info.port_alloc.ext_port     = receive_msg.port;
00493         peer->info.port_alloc.ext_port_set = FLAG_SET;
00494 
00495         /* send a message with the buddy's port, to go back to the buddy port
00496          * state.  there is no need to wait for the port value to be set, it
00497          * is obviously set, since it was set before */
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         /* go to the start direct conncetion state now that all ports are
00506          * known */
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         /* declare local variables */
00518         comm_msg_syn_ack_flood_seq_num_t msg;
00519 
00520         /* error check arguments */
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         /* do function */
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         /* as soon as the bday.seq_num_set flag is set, it is time for this
00532          * peer to flood synacks */
00533         CHECK_FAILED(wait_for_buddy_syn_flood(&buddy->info),ERROR_1);
00534 
00535         /* make the message... */
00536         msg.seq_num = buddy->info.bday.seq_num;
00537         /* ...and sent it */
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         /* enter the next state */
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         /* declare local variables */
00554         comm_msg_buddy_port_t msg;
00555 
00556         /* error check arguments */
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         /* do function */
00562 
00563         /* receive the message indicating the synack flood was done */
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         /* wait for the buddy to set the external port */
00569         CHECK_FAILED(wait_for_buddy_bday_port(&(buddy->info)),ERROR_1);
00570 
00571         /* now, resend the COMM_MSG_BUDDY_PORT message, but this time mark
00572          * the bday flag as unneeded
00573          */
00574         msg.ext_port = buddy->info.bday.port;
00575         msg.bday     = COMM_BDAY_NOT_NEEDED;
00576 
00577         /* now send the message */
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         /* go to the start direct conncetion state now that all ports are
00583          * known */
00584         CHECK_FAILED(helper_fsm_start_direct_conn(list,peer,buddy),
00585                 ERROR_CALLED_FUNCTION);
00586 
00587         return SUCCESS;
00588 
00589 }
00590 

Generated on Wed Mar 30 23:20:47 2005 for NATBLASTER by  doxygen 1.3.9.1