void CCBServer::ForwardRequestToTarget( CCBServerRequest *request, CCBTarget *target ) { Sock *sock = target->getSock(); ClassAd msg; msg.Assign( ATTR_COMMAND, CCB_REQUEST ); msg.Assign( ATTR_MY_ADDRESS, request->getReturnAddr() ); msg.Assign( ATTR_CLAIM_ID, request->getConnectID() ); // for easier debugging msg.Assign( ATTR_NAME, request->getSock()->peer_description() ); MyString reqid_str; CCBIDToString( request->getRequestID(), reqid_str); msg.Assign( ATTR_REQUEST_ID, reqid_str ); sock->encode(); if( !msg.put( *sock ) || !sock->end_of_message() ) { dprintf(D_ALWAYS, "CCB: failed to forward request id %lu from %s to target " "daemon %s with ccbid %lu\n", request->getRequestID(), request->getSock()->peer_description(), target->getSock()->peer_description(), target->getCCBID()); RequestFinished( request, false, "failed to forward request to target" ); return; } // Now wait for target to respond (HandleRequestResultsMsg). // We will get the response next time we poll the socket. // To get a faster response, we _could_ register the socket // now, if it has not already been registered. }
int GetMyProxyPasswordFromSchedD (int cluster_id, int proc_id, char ** password) { // This might seem not necessary, but it IS // For some reason you can't just pass cluster_id to sock->code() directly!!!! int cluster, proc; cluster = cluster_id; proc = proc_id; dprintf ( D_FULLDEBUG, " GetMyProxyPasswordFromSchedD %d, %d\n", cluster_id, proc_id); // Get At Schedd Daemon schedd( DT_SCHEDD ); if( ! schedd.locate() ) { dprintf( D_ALWAYS, "GetMyProxyPasswordFromSchedD: Can't find address of local schedd\n" ); return FALSE; } // Start command Sock* sock; if (!(sock = schedd.startCommand( GET_MYPROXY_PASSWORD, Stream::reli_sock, 0))) { dprintf( D_ALWAYS, "GetMyProxyPasswordFromSchedD: Could not connect to local schedd\n" ); return FALSE; } sock->encode(); if (!sock->code (cluster) || !sock->code(proc)) { dprintf( D_ALWAYS, "GetMyProxyPasswordFromSchedD: Could not encode clusterId, procId\n" ); return FALSE; } sock->end_of_message(); sock->decode(); if (!sock->code (*password)) { dprintf( D_ALWAYS, "GetMyProxyPasswordFromSchedD: Can't retrieve password\n" ); return FALSE; } sock->end_of_message(); sock->close(); delete sock; return TRUE; }
int CCBListener::ReverseConnected(Stream *stream) { Sock *sock = (Sock *)stream; ClassAd *msg_ad = (ClassAd *)daemonCore->GetDataPtr(); ASSERT( msg_ad ); if( sock ) { daemonCore->Cancel_Socket( sock ); } if( !sock || !sock->is_connected() ) { ReportReverseConnectResult(msg_ad,false,"failed to connect"); } else { // The reverse-connect protocol is designed to look like a // raw cedar command, in case the thing we are connecting // to is a cedar command socket. sock->encode(); int cmd = CCB_REVERSE_CONNECT; if( !sock->put(cmd) || !msg_ad->put( *sock ) || !sock->end_of_message() ) { ReportReverseConnectResult(msg_ad,false,"failure writing reverse connect command"); } else { ((ReliSock*)sock)->isClient(false); daemonCore->HandleReqAsync(sock); sock = NULL; // daemonCore took ownership of sock ReportReverseConnectResult(msg_ad,true); } } delete msg_ad; if( sock ) { delete sock; } decRefCount(); // we incremented ref count when setting up callback return KEEP_STREAM; }
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()); }
int main( int argc, char *argv[] ) { const char *filename=0; char *pool=0; int command=-1; int i; bool use_tcp = false; bool with_ack = false; bool allow_multiple = false; param_functions *p_funcs = NULL; myDistro->Init( argc, argv ); config(); p_funcs = get_param_functions(); for( i=1; i<argc; i++ ) { if(!strcmp(argv[i],"-help")) { usage(argv[0]); exit(0); } else if(!strcmp(argv[i],"-pool")) { i++; if(!argv[i]) { fprintf(stderr,"-pool requires an argument.\n\n"); usage(argv[0]); exit(1); } pool = argv[i]; } else if(!strncmp(argv[i],"-tcp",strlen(argv[i]))) { use_tcp = true; } else if(!strncmp(argv[i],"-multiple",strlen(argv[i]))) { // We don't set allow_multiple=true by default, because // existing users (e.g. glideinWMS) have stray blank lines // in the input file. allow_multiple = true; } else if(!strcmp(argv[i],"-version")) { version(); exit(0); } else if(!strcmp(argv[i],"-debug")) { // dprintf to console Termlog = 1; p_funcs = get_param_functions(); dprintf_config ("TOOL", p_funcs); } else if(argv[i][0]!='-' || !strcmp(argv[i],"-")) { if(command==-1) { command = getCollectorCommandNum(argv[i]); if(command==-1) { fprintf(stderr,"Unknown command name %s\n\n",argv[i]); usage(argv[0]); exit(1); } } else if(!filename) { filename = argv[i]; } else { fprintf(stderr,"Extra argument: %s\n\n",argv[i]); usage(argv[0]); exit(1); } } else { fprintf(stderr,"Unknown argument: %s\n\n",argv[i]); usage(argv[0]); exit(1); } } FILE *file; ClassAdList ads; Daemon *collector; Sock *sock; switch( command ) { case UPDATE_STARTD_AD_WITH_ACK: with_ack = true; break; } if( with_ack ) { use_tcp = true; } if(!filename || !strcmp(filename,"-")) { file = stdin; filename = "(stdin)"; } else { file = safe_fopen_wrapper_follow(filename,"r"); } if(!file) { fprintf(stderr,"couldn't open %s: %s\n",filename,strerror(errno)); return 1; } while(!feof(file)) { int eof=0,error=0,empty=0; char const *delim = "\n"; if( !allow_multiple ) { delim = "***"; } ClassAd *ad = new ClassAd(file,const_cast<char *>(delim),eof,error,empty); if(error) { fprintf(stderr,"couldn't parse ClassAd in %s\n",filename); delete ad; return 1; } if( empty ) { delete ad; break; } if( !allow_multiple && ads.Length() > 0 ) { fprintf(stderr,"ERROR: failed to parse '%s' as a ClassAd attribute\n",delim); delete ad; return 1; } ads.Insert(ad); } if(ads.Length() == 0) { fprintf(stderr,"%s is empty\n",filename); return 1; } CollectorList * collectors; if ( pool ) { collector = new Daemon( DT_COLLECTOR, pool, 0 ); collectors = new CollectorList(); collectors->append (collector); } else { collectors = CollectorList::create(); } bool had_error = false; collectors->rewind(); while (collectors->next(collector)) { dprintf(D_FULLDEBUG,"locating collector %s...\n", collector->name()); if(!collector->locate()) { fprintf(stderr,"couldn't locate collector: %s\n",collector->error()); had_error = true; continue; } dprintf(D_FULLDEBUG,"collector is %s located at %s\n", collector->hostname(),collector->addr()); sock = NULL; ClassAd *ad; int success_count = 0; int failure_count = 0; ads.Rewind(); while( (ad=ads.Next()) ) { // If there's no "MyAddress", generate one.. if( !ad->Lookup( ATTR_MY_ADDRESS ) ) { MyString tmp; tmp.formatstr( "<%s:0>", my_ip_string() ); ad->Assign( ATTR_MY_ADDRESS, tmp.Value() ); } if ( use_tcp ) { if( !sock ) { sock = collector->startCommand(command,Stream::reli_sock,20); } else { // Use existing connection. sock->encode(); sock->put(command); } } else { // We must open a new UDP socket each time. delete sock; sock = collector->startCommand(command,Stream::safe_sock,20); } int result = 0; if ( sock ) { result += ad->put( *sock ); result += sock->end_of_message(); } if ( result != 2 ) { fprintf(stderr,"failed to send classad to %s\n",collector->addr()); had_error = true; failure_count++; delete sock; sock = NULL; continue; } if( with_ack ) { sock->decode(); int ok = 0; if( !sock->get(ok) || !sock->end_of_message() ) { fprintf(stderr,"failed to get ack from %s\n",collector->addr()); had_error = true; failure_count++; delete sock; sock = NULL; continue; } // ack protocol does not allow for multiple updates, // so close the socket now delete sock; sock = NULL; } success_count++; } if( sock ) { CondorVersionInfo const *ver = sock->get_peer_version(); if( !ver || ver->built_since_version(7,7,3) ) { // graceful hangup so the collector knows we are done sock->encode(); command = DC_NOP; sock->put(command); sock->end_of_message(); } delete sock; sock = NULL; } printf("Sent %d of %d ad%s to %s.\n", success_count, success_count + failure_count, success_count+failure_count == 1 ? "" : "s", collector->name()); } delete collectors; return (had_error)?1:0; }