bool CCBListener::DoReversedCCBConnect( char const *address, char const *connect_id, char const *request_id, char const *peer_description ) { Daemon daemon( DT_ANY, address ); CondorError errstack; Sock *sock = daemon.makeConnectedSocket( Stream::reli_sock,CCB_TIMEOUT,0,&errstack,true /*nonblocking*/); ClassAd *msg_ad = new ClassAd; ASSERT( msg_ad ); msg_ad->Assign( ATTR_CLAIM_ID, connect_id ); msg_ad->Assign( ATTR_REQUEST_ID, request_id ); // the following is put in the message because that is an easy (lazy) // way to make it available to ReportReverseConnectResult msg_ad->Assign( ATTR_MY_ADDRESS, address); if( !sock ) { // Failed to create socket or initiate connect ReportReverseConnectResult(msg_ad,false,"failed to initiate connection"); delete msg_ad; return false; } if( peer_description ) { char const *peer_ip = sock->peer_ip_str(); if( peer_ip && !strstr(peer_description,peer_ip)) { MyString desc; desc.formatstr("%s at %s",peer_description,sock->get_sinful_peer()); sock->set_peer_description(desc.Value()); } else { sock->set_peer_description(peer_description); } } incRefCount(); // do not delete self until called back MyString sock_desc; int rc = daemonCore->Register_Socket( sock, sock->peer_description(), (SocketHandlercpp)&CCBListener::ReverseConnected, "CCBListener::ReverseConnected", this); if( rc < 0 ) { ReportReverseConnectResult(msg_ad,false,"failed to register socket for non-blocking reversed connection"); delete msg_ad; delete sock; decRefCount(); return false; } rc = daemonCore->Register_DataPtr(msg_ad); ASSERT( rc ); return true; }
void CCBServer::SendHeartbeatResponse( CCBTarget *target ) { Sock *sock = target->getSock(); ClassAd msg; msg.Assign( ATTR_COMMAND, ALIVE ); sock->encode(); if( !msg.put( *sock ) || !sock->end_of_message() ) { dprintf(D_ALWAYS, "CCB: failed to send heartbeat to target " "daemon %s with ccbid %lu\n", target->getSock()->peer_description(), target->getCCBID()); RemoveTarget( target ); return; } dprintf(D_FULLDEBUG,"CCB: sent heartbeat to target %s\n", sock->peer_description()); }
void CCBServer::HandleRequestResultsMsg( CCBTarget *target ) { // Reply from target daemon about whether it succeeded in // connecting to the requested client. Sock *sock = target->getSock(); ClassAd msg; sock->decode(); if( !msg.initFromStream( *sock ) || !sock->end_of_message() ) { // disconnect dprintf(D_FULLDEBUG, "CCB: received disconnect from target daemon %s " "with ccbid %lu.\n", sock->peer_description(), target->getCCBID() ); RemoveTarget( target ); return; } int command = 0; if( msg.LookupInteger( ATTR_COMMAND, command ) && command == ALIVE ) { SendHeartbeatResponse( target ); return; } target->decPendingRequestResults(); bool success = false; MyString error_msg; MyString reqid_str; CCBID reqid; MyString connect_id; msg.LookupBool( ATTR_RESULT, success ); msg.LookupString( ATTR_ERROR_STRING, error_msg ); msg.LookupString( ATTR_REQUEST_ID, reqid_str ); msg.LookupString( ATTR_CLAIM_ID, connect_id ); if( !CCBIDFromString( reqid, reqid_str.Value() ) ) { MyString msg_str; msg.sPrint(msg_str); dprintf(D_ALWAYS, "CCB: received reply from target daemon %s with ccbid %lu " "without a valid request id: %s\n", sock->peer_description(), target->getCCBID(), msg_str.Value()); RemoveTarget( target ); return; } CCBServerRequest *request = GetRequest( reqid ); if( request && request->getSock()->readReady() ) { // Request socket must have just closed. To avoid noise in // logs when we fail to write to it, delete the request now. RemoveRequest( request ); request = NULL; } char const *request_desc = "(client which has gone away)"; if( request ) { request_desc = request->getSock()->peer_description(); } if( success ) { dprintf(D_FULLDEBUG,"CCB: received 'success' from target daemon %s " "with ccbid %lu for " "request %s from %s.\n", sock->peer_description(), target->getCCBID(), reqid_str.Value(), request_desc); } else { dprintf(D_FULLDEBUG,"CCB: received error from target daemon %s " "with ccbid %lu for " "request %s from %s: %s\n", sock->peer_description(), target->getCCBID(), reqid_str.Value(), request_desc, error_msg.Value()); } if( !request ) { if( success ) { // expected: the client has gone away; it got what it wanted return; } dprintf( D_FULLDEBUG, "CCB: client for request %s to target daemon %s with ccbid " "%lu disappeared before receiving error details.\n", reqid_str.Value(), sock->peer_description(), target->getCCBID()); return; } if( connect_id != request->getConnectID() ) { MyString msg_str; msg.sPrint(msg_str); dprintf( D_FULLDEBUG, "CCB: received wrong connect id (%s) from target daemon %s " "with ccbid %lu for " "request %s\n", connect_id.Value(), sock->peer_description(), target->getCCBID(), reqid_str.Value()); RemoveTarget( target ); return; } RequestFinished( request, success, error_msg.Value() ); }