static pmix_status_t connect_to_peer(struct pmix_peer_t *peer, pmix_info_t *info, size_t ninfo) { struct sockaddr_un *address; char *evar, **uri; pmix_status_t rc; int sd; pmix_socklen_t len; bool retried = false; pmix_output_verbose(2, pmix_ptl_base_framework.framework_output, "[%s:%d] connect to server", __FILE__, __LINE__); /* if we are not a client, there is nothing we can do */ if (!PMIX_PROC_IS_CLIENT(pmix_globals.mypeer)) { return PMIX_ERR_NOT_SUPPORTED; } /* if we don't have a path to the daemon rendezvous point, * then we need to return an error */ if (NULL != (evar = getenv("PMIX_SERVER_URI2USOCK"))) { /* this is a v2.1+ server */ pmix_globals.mypeer->nptr->compat.bfrops = pmix_bfrops_base_assign_module("v21"); if (NULL == pmix_globals.mypeer->nptr->compat.bfrops) { return PMIX_ERR_INIT; } } else if (NULL != (evar = getenv("PMIX_SERVER_URI"))) { /* this is a pre-v2.1 server - must use the v12 bfrops module */ pmix_globals.mypeer->nptr->compat.bfrops = pmix_bfrops_base_assign_module("v12"); if (NULL == pmix_globals.mypeer->nptr->compat.bfrops) { return PMIX_ERR_INIT; } } else { /* let the caller know that the server isn't available */ return PMIX_ERR_SERVER_NOT_AVAIL; } /* the server will be using the same bfrops as us */ pmix_client_globals.myserver->nptr->compat.bfrops = pmix_globals.mypeer->nptr->compat.bfrops; /* mark that we are using the V1 protocol */ pmix_globals.mypeer->protocol = PMIX_PROTOCOL_V1; uri = pmix_argv_split(evar, ':'); if (3 != pmix_argv_count(uri)) { pmix_argv_free(uri); PMIX_ERROR_LOG(PMIX_ERROR); return PMIX_ERROR; } /* set the server nspace */ if (NULL == pmix_client_globals.myserver->info) { pmix_client_globals.myserver->info = PMIX_NEW(pmix_rank_info_t); } if (NULL == pmix_client_globals.myserver->nptr) { pmix_client_globals.myserver->nptr = PMIX_NEW(pmix_namespace_t); } if (NULL == pmix_client_globals.myserver->nptr->nspace) { pmix_client_globals.myserver->nptr->nspace = strdup(uri[0]); } if (NULL == pmix_client_globals.myserver->info->pname.nspace) { pmix_client_globals.myserver->info->pname.nspace = strdup(uri[0]); } /* set the server rank */ pmix_client_globals.myserver->info->pname.rank = strtoull(uri[1], NULL, 10); /* setup the path to the daemon rendezvous point */ memset(&mca_ptl_usock_component.connection, 0, sizeof(struct sockaddr_storage)); address = (struct sockaddr_un*)&mca_ptl_usock_component.connection; address->sun_family = AF_UNIX; snprintf(address->sun_path, sizeof(address->sun_path)-1, "%s", uri[2]); /* if the rendezvous file doesn't exist, that's an error */ if (0 != access(uri[2], R_OK)) { pmix_argv_free(uri); PMIX_ERROR_LOG(PMIX_ERR_NOT_FOUND); return PMIX_ERR_NOT_FOUND; } pmix_argv_free(uri); retry: /* establish the connection */ len = sizeof(struct sockaddr_un); if (PMIX_SUCCESS != (rc = pmix_ptl_base_connect(&mca_ptl_usock_component.connection, len, &sd))) { PMIX_ERROR_LOG(rc); return rc; } pmix_client_globals.myserver->sd = sd; /* send our identity and any authentication credentials to the server */ if (PMIX_SUCCESS != (rc = send_connect_ack(sd))) { CLOSE_THE_SOCKET(sd); return rc; } /* do whatever handshake is required */ if (PMIX_SUCCESS != (rc = recv_connect_ack(sd))) { CLOSE_THE_SOCKET(sd); if (PMIX_ERR_TEMP_UNAVAILABLE == rc) { /* give it two tries */ if (!retried) { retried = true; goto retry; } } return rc; } pmix_output_verbose(2, pmix_ptl_base_framework.framework_output, "sock_peer_try_connect: Connection across to server succeeded"); /* mark the connection as made */ pmix_globals.connected = true; pmix_ptl_base_set_nonblocking(sd); /* setup recv event */ pmix_event_assign(&pmix_client_globals.myserver->recv_event, pmix_globals.evbase, pmix_client_globals.myserver->sd, EV_READ | EV_PERSIST, pmix_usock_recv_handler, pmix_client_globals.myserver); pmix_event_add(&pmix_client_globals.myserver->recv_event, 0); pmix_client_globals.myserver->recv_ev_active = true; PMIX_POST_OBJECT(pmix_client_globals.myserver); pmix_event_add(&pmix_client_globals.myserver->recv_event, 0); /* setup send event */ pmix_event_assign(&pmix_client_globals.myserver->send_event, pmix_globals.evbase, pmix_client_globals.myserver->sd, EV_WRITE|EV_PERSIST, pmix_usock_send_handler, pmix_client_globals.myserver); pmix_client_globals.myserver->send_ev_active = false; return PMIX_SUCCESS; }
static void uni_call(SOCKET *sock,unsigned char mid) { char buffer[MAX_ATM_ADDR_LEN+1]; int error; switch (mid) { case ATM_MSG_STATUS: /* 5.5.6.12 */ { CALL_STATE state; /* * NOTE: T322 isn't implemented yet, but when it is, make sure * to only stop it on STATUS iff the cause is * ATM_CV_RESP_STAT_ENQ. Supplementary services break if * you stop on any STATUS. */ state = q_fetch(&in_dsc,QF_call_state); if (state == cs_null) break; /* clear call */ if (sock->call_state == cs_rel_req || sock->call_state == cs_rel_ind) return; if (state != sock->call_state) diag(COMPONENT,DIAG_WARN,"STATUS %s received in state %s", cs_name[state],cs_name[sock->call_state]); } return; default: ; } switch (mid) { case ATM_MSG_CALL_PROC: /* CONNECTING, WAIT_REL, REL_REQ */ if (sock->state == ss_wait_rel || sock->state == ss_rel_req) { send_status(sock->sig,sock,0,ATM_CV_INCOMP_MSG, ATM_MSG_CALL_PROC); return; } if (sock->state != ss_connecting) break; /* check for 2nd CALL_PROC @@@ */ STOP_TIMER(sock); if (q_present(&in_dsc,QG_conn_id)) { int vpci; vpci = q_fetch(&in_dsc,QF_vpi); sock->pvc.sap_family = AF_ATMPVC; sock->pvc.sap_addr.itf = get_itf(sock->sig,&vpci); sock->pvc.sap_addr.vpi = vpci; sock->pvc.sap_addr.vci = q_fetch(&in_dsc,QF_vci); diag(COMPONENT,DIAG_DEBUG,"ITF.VPI.VCI: %d.%d.%d", sock->pvc.sap_addr.itf,sock->pvc.sap_addr.vpi, sock->pvc.sap_addr.vci); } START_TIMER(sock,T310); sock->call_state = cs_out_proc; return; case ATM_MSG_CONNECT: /* CONNECTING, REL_REQ */ if (sock->state == ss_rel_req) { send_status(sock->sig,sock,0,ATM_CV_INCOMP_MSG,ATM_MSG_CONNECT); return; } if (sock->state != ss_connecting) break; STOP_TIMER(sock); if (q_present(&in_dsc,QG_conn_id)) { int vpci; vpci = q_fetch(&in_dsc,QF_vpi); sock->pvc.sap_family = AF_ATMPVC; sock->pvc.sap_addr.itf = get_itf(sock->sig,&vpci); sock->pvc.sap_addr.vpi = vpci; sock->pvc.sap_addr.vci = q_fetch(&in_dsc,QF_vci); diag(COMPONENT,DIAG_DEBUG,"ITF.VPI.VCI: %d/%d.%d", sock->pvc.sap_addr.itf,sock->pvc.sap_addr.vpi, sock->pvc.sap_addr.vci); } error = 0; if (!sock->pvc.sap_addr.vpi && !sock->pvc.sap_addr.vci) error = -EPROTO; /* more problems */ if (error) { set_error(sock,error); send_release(sock,0); /* @@@ cause follows reason ??? */ START_TIMER(sock,T308_1); new_state(sock,ss_rel_req); return; } send_connect_ack(sock); /* @@@ fill in sock->remote */ /* @@@ fill in traffic parameters */ send_kernel(sock->id,kptr_null,as_okay,0,&sock->pvc,NULL, &sock->local,&sock->sap,&sock->qos); new_state(sock,ss_connected); #if defined(Q2963_1) || defined(DYNAMIC_UNI) sock->owner = 1; #endif if (atm2text(buffer,MAX_ATM_ADDR_LEN+1,(struct sockaddr *) &sock->remote,0) < 0) strcpy(buffer,"<invalid>"); diag(COMPONENT,DIAG_INFO,"Active open succeeded (CR 0x%06X, " "ID %s, to %s)",sock->call_ref,kptr_print(&sock->id),buffer); return; case ATM_MSG_CONN_ACK: /* ACCEPTING, WAIT_REL, REL_REQ */ diag(COMPONENT,DIAG_DEBUG,"CA vpi.vci=%d.%d", sock->pvc.sap_addr.vpi,sock->pvc.sap_addr.vci); if (sock->state == ss_wait_rel || sock->state == ss_rel_req) { send_status(sock->sig,sock,0,ATM_CV_INCOMP_MSG, ATM_MSG_CONN_ACK); return; } if (sock->state != ss_accepting) break; STOP_TIMER(sock); send_kernel(sock->id,kptr_null,as_okay,0,NULL,NULL,&sock->local, &sock->sap,NULL); new_state(sock,ss_connected); #if defined(Q2963_1) || defined(DYNAMIC_UNI) sock->owner = 0; #endif if (atm2text(buffer,MAX_ATM_ADDR_LEN+1, (struct sockaddr *) &sock->remote,0) < 0) strcpy(buffer,"<invalid>"); diag(COMPONENT,DIAG_INFO,"Passive open succeeded (CR 0x%06X, " "ID %s, from %s)",sock->call_ref,kptr_print(&sock->id),buffer); return; case ATM_MSG_RELEASE: /* all states */ { unsigned char cause; cause = q_fetch(&in_dsc,QF_cause); diag(COMPONENT,DIAG_DEBUG,"Cause %d (%s)",cause,cause > 127 ? "invalid cause" : cause_text[cause]); } switch (sock->state) { case ss_connecting: set_error(sock,-ECONNREFUSED); /* fall through */ case ss_accepting: set_error(sock,-ECONNRESET); /* ERESTARTSYS ? */ send_release_complete(sock->sig,sock->call_ref,0); SEND_ERROR(sock->id,sock->error); STOP_TIMER(sock); free_sock(sock); return; case ss_rel_req: send_close(sock); /* fall through */ case ss_wait_rel: STOP_TIMER(sock); free_sock(sock); return; #if defined(Q2963_1) || defined(DYNAMIC_UNI) case ss_mod_req: #endif STOP_TIMER(sock); /* fall through */ #if defined(Q2963_1) || defined(DYNAMIC_UNI) case ss_mod_lcl: case ss_mod_rcv: case ss_mod_fin_ok: case ss_mod_fin_fail: case ss_mod_fin_ack: #endif case ss_connected: diag(COMPONENT,DIAG_INFO,"Passive close (CR 0x%06X)", sock->call_ref); #if defined(Q2963_1) || defined(DYNAMIC_UNI) if (timer_handler(sock->conn_timer) == on_T361) STOP_TIMER(sock); #endif send_close(sock); new_state(sock,ss_rel_ind); return; case ss_indicated: /* fall through */ case ss_proceeding: send_release_complete(sock->sig,sock->call_ref,0); new_state(sock,ss_zombie); /* fall through */ case ss_rel_ind: return; default: send_release_complete(sock->sig,sock->call_ref,0); /* @@@ should be ATM_CV_INCOMP_MSG */ break; } break; case ATM_MSG_RESTART: set_error(sock,-ENETRESET); /* fall through */ case ATM_MSG_STATUS: /* fall through when clearing */ case ATM_MSG_REL_COMP: /* basically any state (except LISTENING and ZOMBIE) */ { unsigned char cause; if (mid != ATM_MSG_REL_COMP || !q_present(&in_dsc,QF_cause)) cause = 0; else { cause = q_fetch(&in_dsc,QF_cause); diag(COMPONENT,DIAG_DEBUG,"Cause %d (%s)",cause, cause > 127 ? "invalid cause" : cause_text[cause]); } switch (sock->state) { case ss_connecting: set_error(sock,cause == ATM_CV_UNALLOC ? -EADDRNOTAVAIL : cause == ATM_CV_RES_UNAVAIL || #if defined(UNI31) || defined(UNI40) || defined(DYNAMIC_UNI) cause == ATM_CV_UCR_UNAVAIL_NEW || #endif cause == ATM_CV_NO_ROUTE_DEST ? -EHOSTUNREACH : cause == ATM_CV_NUM_CHANGED ? -EREMCHG : cause == ATM_CV_DEST_OOO ? -EHOSTDOWN : -ECONNREFUSED); /* fall through */ case ss_accepting: set_error(sock,-ECONNRESET); /* ERESTARTSYS ? */ SEND_ERROR(sock->id,sock->error); STOP_TIMER(sock); free_sock(sock); return; case ss_rel_req: send_close(sock); /* fall through */ case ss_wait_rel: STOP_TIMER(sock); free_sock(sock); return; #if defined(Q2963_1) || defined(DYNAMIC_UNI) case ss_mod_req: #endif STOP_TIMER(sock); /* fall through */ #if defined(Q2963_1) || defined(DYNAMIC_UNI) case ss_mod_lcl: case ss_mod_rcv: case ss_mod_fin_ok: case ss_mod_fin_fail: case ss_mod_fin_ack: #endif case ss_connected: diag(COMPONENT,DIAG_INFO,"Passive close (CR 0x%06X)", sock->call_ref); #if defined(Q2963_1) || defined(DYNAMIC_UNI) if (timer_handler(sock->conn_timer) == on_T361) STOP_TIMER(sock); #endif send_close(sock); /* fall through */ case ss_rel_ind: new_state(sock,ss_wait_close); return; case ss_indicated: /* fall through */ case ss_proceeding: new_state(sock,ss_zombie); return; default: break; } break; /* fail */ } case ATM_MSG_ALERTING: /* * We basically ignore this junk message, except for the connection * identifier it may carry. */ if (q_present(&in_dsc,QG_conn_id)) { int vpci; vpci = q_fetch(&in_dsc,QF_vpi); sock->pvc.sap_family = AF_ATMPVC; sock->pvc.sap_addr.itf = get_itf(sock->sig,&vpci); sock->pvc.sap_addr.vpi = vpci; sock->pvc.sap_addr.vci = q_fetch(&in_dsc,QF_vci); diag(COMPONENT,DIAG_DEBUG,"ITF.VPI.VCI: %d.%d.%d", sock->pvc.sap_addr.itf,sock->pvc.sap_addr.vpi, sock->pvc.sap_addr.vci); } return; case ATM_MSG_NOTIFY: /* silently ignore this junk */ return; #if defined(Q2963_1) || defined(DYNAMIC_UNI) /* * Buglet ahead: should actually test "call_state" */ case ATM_MSG_MODIFY_REQ: if (!(sock->sig->uni & S_Q2963_1)) goto _default; if (sock->state != ss_connected || sock->owner) break; sock->new_qos = sock->qos; if (q_present(&in_dsc,QF_fw_pcr_01)) sock->new_qos.rxtp.max_pcr = q_fetch(&in_dsc,QF_fw_pcr_01); if (q_present(&in_dsc,QF_bw_pcr_01)) sock->new_qos.txtp.max_pcr = q_fetch(&in_dsc,QF_bw_pcr_01); send_kernel(sock->id,kptr_null,as_modify, ATM_MF_INC_RSV | ATM_MF_DEC_RSV | ATM_MF_DEC_SHP, NULL,NULL,NULL,NULL,&sock->new_qos); new_state(sock,ss_mod_rcv); return; case ATM_MSG_MODIFY_ACK: if (!(sock->sig->uni & S_Q2963_1)) goto _default; if (sock->state != ss_mod_req) break; STOP_TIMER(sock); sock->qos = sock->new_qos; if (q_present(&in_dsc,QG_bbrt)) send_conn_avail(sock); send_kernel(sock->id,kptr_null,as_modify,ATM_MF_SET,NULL,NULL,NULL, NULL,&sock->qos); new_state(sock,ss_mod_fin_ok); return; case ATM_MSG_MODIFY_REJ: if (!(sock->sig->uni & S_Q2963_1)) goto _default; if (sock->state != ss_mod_req) break; STOP_TIMER(sock); sock->error = -EAGAIN; send_kernel(sock->id,kptr_null,as_modify,ATM_MF_SET,NULL,NULL,NULL, NULL,&sock->qos); new_state(sock,ss_mod_fin_fail); return; case ATM_MSG_CONN_AVAIL: if (!(sock->sig->uni & S_Q2963_1)) goto _default; if (sock->state != ss_connected || sock->owner) break; STOP_TIMER(sock); send_kernel(sock->id,kptr_null,as_modify,ATM_MF_SET,NULL,NULL,NULL, NULL,&sock->qos); new_state(sock,ss_mod_fin_ack); return; _default: /* jump here if we don't want to understand a message */ #endif default: diag(COMPONENT,DIAG_WARN,"Bad signaling message %d",mid); send_status(sock->sig,sock,0,ATM_CV_UNKNOWN_MSG_TYPE,mid); return; } diag(COMPONENT,DIAG_WARN, "Signaling message %s is incompatible with state %s/%s (%d?%d)", mid2name(mid),state_name[sock->state],cs_name[sock->call_state], (int) sock->state,(int) sock->call_state); send_status(sock->sig,sock,0,ATM_CV_INCOMP_MSG,mid); }
static pmix_status_t try_connect(int *sd) { char *p, *p2, *host; struct sockaddr_in *in; struct sockaddr_in6 *in6; size_t len; pmix_status_t rc; bool retried = false; pmix_output_verbose(2, pmix_ptl_base_framework.framework_output, "pmix:tcp try connect to %s", mca_ptl_tcp_component.super.uri); /* mark that we are the active module for this server */ pmix_client_globals.myserver->nptr->compat.ptl = &pmix_ptl_tcp_module; /* setup the path to the daemon rendezvous point */ memset(&mca_ptl_tcp_component.connection, 0, sizeof(struct sockaddr_storage)); if (0 == strncmp(mca_ptl_tcp_component.super.uri, "tcp4", 4)) { /* need to skip the tcp4: part */ p = strdup(&mca_ptl_tcp_component.super.uri[7]); if (NULL == p) { PMIX_ERROR_LOG(PMIX_ERR_NOMEM); return PMIX_ERR_NOMEM; } /* separate the IP address from the port */ p2 = strchr(p, ':'); if (NULL == p2) { free(p); PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); return PMIX_ERR_BAD_PARAM; } *p2 = '\0'; p2++; host = p; /* load the address */ in = (struct sockaddr_in*)&mca_ptl_tcp_component.connection; in->sin_family = AF_INET; in->sin_addr.s_addr = inet_addr(host); if (in->sin_addr.s_addr == INADDR_NONE) { free(p); PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); return PMIX_ERR_BAD_PARAM; } in->sin_port = htons(atoi(p2)); len = sizeof(struct sockaddr_in); } else { /* need to skip the tcp6: part */ p = strdup(&mca_ptl_tcp_component.super.uri[7]); if (NULL == p) { PMIX_ERROR_LOG(PMIX_ERR_NOMEM); return PMIX_ERR_NOMEM; } p2 = strchr(p, ':'); if (NULL == p2) { free(p); PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); return PMIX_ERR_BAD_PARAM; } *p2 = '\0'; if (']' == p[strlen(p)-1]) { p[strlen(p)-1] = '\0'; } if ('[' == p[0]) { host = &p[1]; } else { host = &p[0]; } /* load the address */ in6 = (struct sockaddr_in6*)&mca_ptl_tcp_component.connection; in6->sin6_family = AF_INET6; if (0 == inet_pton(AF_INET6, host, (void*)&in6->sin6_addr)) { pmix_output (0, "ptl_tcp_parse_uri: Could not convert %s\n", host); free(p); PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); return PMIX_ERR_BAD_PARAM; } in6->sin6_port = htons(atoi(p2)); len = sizeof(struct sockaddr_in6); } free(p); retry: /* establish the connection */ if (PMIX_SUCCESS != (rc = pmix_ptl_base_connect(&mca_ptl_tcp_component.connection, len, sd))) { /* do not error log - might just be a stale connection point */ return rc; } /* send our identity and any authentication credentials to the server */ if (PMIX_SUCCESS != (rc = send_connect_ack(*sd))) { PMIX_ERROR_LOG(rc); CLOSE_THE_SOCKET(*sd); return rc; } /* do whatever handshake is required */ if (PMIX_SUCCESS != (rc = recv_connect_ack(*sd))) { CLOSE_THE_SOCKET(*sd); if (PMIX_ERR_TEMP_UNAVAILABLE == rc) { /* give it two tries */ if (!retried) { retried = true; goto retry; } } PMIX_ERROR_LOG(rc); return rc; } return PMIX_SUCCESS; }
/* * ******************************************* * Function: handle_transport_layer_packet * * Description: * * handle a transport layer * packet. Core transport layer handling * function , all the other funcitons * were written to support this big guy * * Parameters: * buffer - packet buffer * src_id - Source id * dest_id - Destination id * * ******************************************* */ void handle_transport_layer_packet( void * buffer , int src_id , int dest_id ) { int packet_type; int requested_mtu; int seq_no; int connect_id; void *realloc_buffer; int win_size ; void *packet_data; int cid_seq_no; int current_sender_id; int current_cid_state; int sender_id ; char *realloc_buf_ptr; int max_connections_permitted = get_state(&__max_connections); packet_type = get_packet_type(buffer); switch(packet_type) { case CONTROL_CONNECT: requested_mtu = get_requested_mtu(buffer); connect_id =allocate_sender(max_connections_permitted); sender_id = get_sender_id(buffer); if ( connect_id < max_connections_permitted) { init_state(&__session_tab.cid_info[connect_id].curr_state); set_state(&__session_tab.cid_info[connect_id].curr_state ,STATE_CONNECTED); __session_tab.cid_info[connect_id].sequence_number = 0; __session_tab.cid_info[connect_id].buf_len = 0; send_connect_ack(src_id , requested_mtu , connect_id,sender_id); } else { fprintf(stderr ,"%s", "\n Connection not possilbe all slots full \n"); } break; case CONTROL_ACK: seq_no = get_sequence_number(buffer); current_sender_id = get_sender_id(buffer); connect_id = get_cid(buffer); sender_buffer[current_sender_id].seq_no = seq_no; sender_buffer[current_sender_id].response_code = CONTROL_ACK; sender_buffer[current_sender_id].connection_id = connect_id; break; case CONTROL_DATA: { fprintf(stderr,"DATA packet received ... "); connect_id = get_cid(buffer); seq_no = get_sequence_number(buffer); sender_id = get_sender_id(buffer); cid_seq_no = __session_tab.cid_info[connect_id].sequence_number; current_cid_state = get_state(&__session_tab.cid_info[connect_id].curr_state); fprintf(stderr,"\n seq no = %d cid seq no = %d window size = %d CID = %d" , seq_no , cid_seq_no , get_window_size(buffer) , connect_id); /* are we getting the next sequnce number & we are connected */ if( ( seq_no == cid_seq_no + 1 ) ) { win_size = get_window_size(buffer); realloc_buffer = malloc(win_size + __session_tab.cid_info[connect_id].buf_len); if ( __session_tab.cid_info[connect_id].buf_len > 0 && ( current_cid_state != STATE_CLOSE)) { memcpy(realloc_buffer,__session_tab.cid_info[connect_id].data_buf,__session_tab.cid_info[connect_id].buf_len); realloc_buf_ptr = (char *) realloc_buffer + __session_tab.cid_info[connect_id].buf_len ; packet_data = (char *) buffer + TRASPORT_LAYER_SIZE ; memcpy(realloc_buf_ptr,packet_data , win_size); __session_tab.cid_info[connect_id].buf_len += win_size; free( __session_tab.cid_info[connect_id].data_buf); __session_tab.cid_info[connect_id].data_buf = realloc_buffer; __session_tab.cid_info[connect_id].sequence_number++; send_ack_request(src_id,seq_no,sender_id) ; } else { packet_data = (char *) buffer + TRASPORT_LAYER_SIZE ; memcpy(realloc_buffer,packet_data , win_size); __session_tab.cid_info[connect_id].buf_len += win_size; __session_tab.cid_info[connect_id].data_buf = realloc_buffer; __session_tab.cid_info[connect_id].sequence_number++; send_ack_request(src_id,seq_no,sender_id) ; } } else if ( seq_no == cid_seq_no ) { send_ack_request(src_id,seq_no,sender_id) ; } else { fprintf(stderr , "%s" , "\n Packet out of sequence number / duplicate discarded \n "); } } break; case CONTROL_FIN: fprintf(stderr ,"\n fin received "); connect_id = get_cid(buffer); sender_id = get_sender_id(buffer); current_cid_state = get_state(&__session_tab.cid_info[connect_id].curr_state); if ( current_cid_state == STATE_CONNECTED ) { nfd_buffer_receved(__session_tab.cid_info[connect_id].data_buf,__session_tab.cid_info[connect_id].buf_len); free(__session_tab.cid_info[connect_id].data_buf); __session_tab.cid_info[connect_id].buf_len = 0 ; } else { set_state(&__session_tab.cid_info[connect_id].curr_state,STATE_FIN); } send_ack_request(src_id,0,sender_id); break; case CONTROL_CLOSE: connect_id = get_cid(buffer); set_state(&__session_tab.cid_info[connect_id].curr_state,STATE_CLOSE); deallocate_connection(connect_id); fprintf(stderr , "\nRecevied close packet "); break; case CONTROL_CONNECT_ACK: seq_no = get_sequence_number(buffer); current_sender_id = get_sender_id(buffer); connect_id = get_cid(buffer); sender_buffer[current_sender_id].response_code = CONTROL_CONNECT_ACK; sender_buffer[current_sender_id].mtu_possible = get_window_size(buffer); sender_buffer[current_sender_id].connection_id = connect_id; fprintf(stderr , "\n Recieved control connect ack sender id %d mtu_possible %d " ,current_sender_id, sender_buffer[current_sender_id].mtu_possible ); break; default: /* None of the known control types */ /* dropping packet */ fprintf(stderr,"\n Not one of the known packet types, Type = %d " , packet_type ); break; } }
static pmix_status_t connect_to_peer(struct pmix_peer_t *peer, pmix_info_t *info, size_t ninfo) { char *evar, **uri; char *filename, *host; FILE *fp; char *srvr, *p, *p2; struct sockaddr_in *in; struct sockaddr_in6 *in6; pmix_socklen_t len; int sd, rc; pmix_output_verbose(2, pmix_globals.debug_output, "ptl:tcp: connecting to server"); /* see if the connection info is in the info array - if * so, then that overrides all other options */ /* if I am a client, then we need to look for the appropriate * connection info in the environment */ if (PMIX_PROC_CLIENT == pmix_globals.proc_type) { if (NULL == (evar = getenv("PMIX_SERVER_URI2"))) { /* not us */ return PMIX_ERR_NOT_SUPPORTED; } /* the URI consists of elements: * - server nspace.rank * - ptl rendezvous URI */ uri = pmix_argv_split(evar, ';'); if (2 != pmix_argv_count(uri)) { PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); pmix_argv_free(uri); return PMIX_ERR_NOT_SUPPORTED; } /* set the server nspace */ p = uri[0]; if (NULL == (p2 = strchr(p, '.'))) { PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); pmix_argv_free(uri); return PMIX_ERR_NOT_SUPPORTED; } *p2 = '\0'; ++p2; pmix_client_globals.myserver.info = PMIX_NEW(pmix_rank_info_t); pmix_client_globals.myserver.info->nptr = PMIX_NEW(pmix_nspace_t); (void)strncpy(pmix_client_globals.myserver.info->nptr->nspace, p, PMIX_MAX_NSLEN); /* set the server rank */ pmix_client_globals.myserver.info->rank = strtoull(p2, NULL, 10); /* save the URI, but do not overwrite what we may have received from * the info-key directives */ if (NULL == mca_ptl_tcp_component.super.uri) { mca_ptl_tcp_component.super.uri = strdup(uri[1]); } pmix_argv_free(uri); } else if (PMIX_PROC_TOOL == pmix_globals.proc_type) { /* if we already have a URI, then look no further */ if (NULL == mca_ptl_tcp_component.super.uri) { /* we have to discover the connection info, * if possible. Start by looking for the connection * info in the expected place - if the server supports * tool connections via TCP, then there will be a * "contact.txt" file under the system tmpdir */ filename = pmix_os_path(false, mca_ptl_tcp_component.tmpdir, "pmix-contact.txt", NULL); if (NULL == filename) { return PMIX_ERR_NOMEM; } fp = fopen(filename, "r"); if (NULL == fp) { /* if we cannot open the file, then the server must not * be configured to support tool connections - so abort */ free(filename); return PMIX_ERR_UNREACH; } free(filename); /* get the URI */ srvr = pmix_getline(fp); if (NULL == srvr) { PMIX_ERROR_LOG(PMIX_ERR_FILE_READ_FAILURE); fclose(fp); return PMIX_ERR_UNREACH; } fclose(fp); /* up to the first ';' is the server nspace/rank */ if (NULL == (p = strchr(srvr, ';'))) { /* malformed */ free(srvr); return PMIX_ERR_UNREACH; } *p = '\0'; ++p; // move past the semicolon /* the nspace is the section up to the '.' */ if (NULL == (p2 = strchr(srvr, '.'))) { /* malformed */ free(srvr); return PMIX_ERR_UNREACH; } *p2 = '\0'; ++p2; /* set the server nspace */ pmix_client_globals.myserver.info = PMIX_NEW(pmix_rank_info_t); pmix_client_globals.myserver.info->nptr = PMIX_NEW(pmix_nspace_t); (void)strncpy(pmix_client_globals.myserver.info->nptr->nspace, srvr, PMIX_MAX_NSLEN); pmix_client_globals.myserver.info->rank = strtoull(p2, NULL, 10); /* now parse the uti itself */ mca_ptl_tcp_component.super.uri = strdup(p); free(srvr); } } /* mark that we are the active module for this server */ pmix_client_globals.myserver.compat.ptl = &pmix_ptl_tcp_module; /* setup the path to the daemon rendezvous point */ memset(&mca_ptl_tcp_component.connection, 0, sizeof(struct sockaddr_storage)); if (0 == strncmp(mca_ptl_tcp_component.super.uri, "tcp4", 4)) { /* separate the IP address from the port */ p = strdup(mca_ptl_tcp_component.super.uri); if (NULL == p) { return PMIX_ERR_NOMEM; } p2 = strchr(&p[7], ':'); if (NULL == p2) { free(p); return PMIX_ERR_BAD_PARAM; } *p2 = '\0'; ++p2; host = &p[7]; /* load the address */ in = (struct sockaddr_in*)&mca_ptl_tcp_component.connection; in->sin_family = AF_INET; in->sin_addr.s_addr = inet_addr(host); if (in->sin_addr.s_addr == INADDR_NONE) { free(p); return PMIX_ERR_BAD_PARAM; } in->sin_port = htons(atoi(p2)); len = sizeof(struct sockaddr_in); } else { /* separate the IP address from the port */ p = strdup(mca_ptl_tcp_component.super.uri); if (NULL == p) { return PMIX_ERR_NOMEM; } p2 = strchr(&p[7], ':'); if (NULL == p2) { free(p); return PMIX_ERR_BAD_PARAM; } *p2 = '\0'; if (']' == p[strlen(p)-1]) { p[strlen(p)-1] = '\0'; } if ('[' == p[7]) { host = &p[8]; } else { host = &p[7]; } /* load the address */ in6 = (struct sockaddr_in6*)&mca_ptl_tcp_component.connection; in6->sin6_family = AF_INET6; if (0 == inet_pton(AF_INET6, host, (void*)&in6->sin6_addr)) { pmix_output (0, "ptl_tcp_parse_uri: Could not convert %s\n", host); free(p); return PMIX_ERR_BAD_PARAM; } in6->sin6_port = htons(atoi(p2)); len = sizeof(struct sockaddr_in6); } free(p); /* establish the connection */ if (PMIX_SUCCESS != (rc = pmix_ptl_base_connect(&mca_ptl_tcp_component.connection, len, &sd))) { PMIX_ERROR_LOG(rc); return rc; } pmix_client_globals.myserver.sd = sd; /* send our identity and any authentication credentials to the server */ if (PMIX_SUCCESS != (rc = send_connect_ack(sd))) { PMIX_ERROR_LOG(rc); CLOSE_THE_SOCKET(sd); return rc; } /* do whatever handshake is required */ if (PMIX_SUCCESS != (rc = recv_connect_ack(sd))) { PMIX_ERROR_LOG(rc); CLOSE_THE_SOCKET(sd); return rc; } pmix_output_verbose(2, pmix_globals.debug_output, "sock_peer_try_connect: Connection across to server succeeded"); /* mark the connection as made */ pmix_globals.connected = true; pmix_ptl_base_set_nonblocking(sd); /* setup recv event */ pmix_event_assign(&pmix_client_globals.myserver.recv_event, pmix_globals.evbase, pmix_client_globals.myserver.sd, EV_READ | EV_PERSIST, pmix_ptl_base_recv_handler, &pmix_client_globals.myserver); pmix_event_add(&pmix_client_globals.myserver.recv_event, 0); pmix_client_globals.myserver.recv_ev_active = true; /* setup send event */ pmix_event_assign(&pmix_client_globals.myserver.send_event, pmix_globals.evbase, pmix_client_globals.myserver.sd, EV_WRITE|EV_PERSIST, pmix_ptl_base_send_handler, &pmix_client_globals.myserver); pmix_client_globals.myserver.send_ev_active = false; return PMIX_SUCCESS; }
static pmix_status_t connect_to_peer(struct pmix_peer_t *peer, pmix_info_t *info, size_t ninfo) { struct sockaddr_un *address; char *evar, **uri; pmix_status_t rc; int sd; pmix_socklen_t len; /* if we are not a client, there is nothing we can do */ if (!PMIX_PROC_IS_CLIENT) { return PMIX_ERR_NOT_SUPPORTED; } /* if we don't have a path to the daemon rendezvous point, * then we need to return an error */ if (NULL == (evar = getenv("PMIX_SERVER_URI"))) { /* let the caller know that the server isn't available */ return PMIX_ERR_SERVER_NOT_AVAIL; } uri = pmix_argv_split(evar, ':'); if (3 != pmix_argv_count(uri)) { pmix_argv_free(uri); return PMIX_ERROR; } /* set the server nspace */ if (NULL == pmix_client_globals.myserver->info) { pmix_client_globals.myserver->info = PMIX_NEW(pmix_rank_info_t); } if (NULL == pmix_client_globals.myserver->nptr) { pmix_client_globals.myserver->nptr = PMIX_NEW(pmix_nspace_t); } if (NULL == pmix_client_globals.myserver->nptr->nspace) { pmix_client_globals.myserver->nptr->nspace = strdup(uri[0]); } if (NULL == pmix_client_globals.myserver->info->pname.nspace) { pmix_client_globals.myserver->info->pname.nspace = strdup(uri[0]); } /* set the server rank */ pmix_client_globals.myserver->info->pname.rank = strtoull(uri[1], NULL, 10); /* setup the path to the daemon rendezvous point */ memset(&mca_ptl_usock_component.connection, 0, sizeof(struct sockaddr_storage)); address = (struct sockaddr_un*)&mca_ptl_usock_component.connection; address->sun_family = AF_UNIX; snprintf(address->sun_path, sizeof(address->sun_path)-1, "%s", uri[2]); /* if the rendezvous file doesn't exist, that's an error */ if (0 != access(uri[2], R_OK)) { pmix_argv_free(uri); return PMIX_ERR_NOT_FOUND; } pmix_argv_free(uri); /* establish the connection */ len = sizeof(struct sockaddr_un); if (PMIX_SUCCESS != (rc = pmix_ptl_base_connect(&mca_ptl_usock_component.connection, len, &sd))) { PMIX_ERROR_LOG(rc); return rc; } pmix_client_globals.myserver->sd = sd; /* send our identity and any authentication credentials to the server */ if (PMIX_SUCCESS != (rc = send_connect_ack(sd))) { CLOSE_THE_SOCKET(sd); return rc; } /* do whatever handshake is required */ if (PMIX_SUCCESS != (rc = recv_connect_ack(sd))) { CLOSE_THE_SOCKET(sd); return rc; } pmix_output_verbose(2, pmix_globals.debug_output, "sock_peer_try_connect: Connection across to server succeeded"); /* mark the connection as made */ pmix_globals.connected = true; pmix_ptl_base_set_nonblocking(sd); /* setup recv event */ pmix_event_assign(&pmix_client_globals.myserver->recv_event, pmix_globals.evbase, pmix_client_globals.myserver->sd, EV_READ | EV_PERSIST, pmix_ptl_base_recv_handler, &pmix_client_globals.myserver); pmix_event_add(&pmix_client_globals.myserver->recv_event, 0); pmix_client_globals.myserver->recv_ev_active = true; /* setup send event */ pmix_event_assign(&pmix_client_globals.myserver->send_event, pmix_globals.evbase, pmix_client_globals.myserver->sd, EV_WRITE|EV_PERSIST, pmix_ptl_base_send_handler, &pmix_client_globals.myserver); pmix_client_globals.myserver->send_ev_active = false; return PMIX_SUCCESS; }