// . returns false if blocked, true otherwise // . sets g_errno on error // . calls gotDocIds to send a reply void Msg39::getDocIds ( UdpSlot *slot ) { // remember the slot m_slot = slot; // reset this m_errno = 0; // get the request m_r = (Msg39Request *) m_slot->m_readBuf; int32_t requestSize = m_slot->m_readBufSize; // ensure it's size is ok if ( requestSize < 8 ) { g_errno = EBADREQUESTSIZE; log(LOG_LOGIC,"query: msg39: getDocIds: %s." , mstrerror(g_errno) ); sendReply ( m_slot , this , NULL , 0 , 0 , true ); return ; } // deserialize it before we do anything else int32_t finalSize = deserializeMsg ( sizeof(Msg39Request) , &m_r->size_readSizes , &m_r->size_whiteList,//coll , &m_r->ptr_readSizes, m_r->m_buf ); // sanity check if ( finalSize != requestSize ) {char *xx=NULL;*xx=0; } getDocIds2 ( m_r ); }
// convert offsets back into ptrs int32_t Msg20Reply::deserialize ( ) { int32_t bytesParsed = deserializeMsg(sizeof(*this), &size_tbuf, &size_note, &ptr_tbuf, ((char*)this) + sizeof(*this)); if(bytesParsed<0) return bytesParsed; // sanity if ( ptr_linkInfo && ((LinkInfo *)ptr_linkInfo)->m_lisize != size_linkInfo ) { log("xmldoc: deserialize msg20 reply corruption error"); log("xmldoc: DO YOU NEED TO NUKE CACHEDB.DAT?????"); return -1; } // return how many bytes we used return bytesParsed; }
Msg_t rcvmessage(Channel ch){ if(ch == NULL){ printf("\nServer listening on port 7000 ...\n\n"); }else{ printf("Client server listening on port %d ... \n", ch->port); } Msg_t msg = (Msg_t) calloc(1, sizeof(msg_t)); int msgSize; int client_len = SOCKET_SIZE; void * bytestring; void * aux; struct sockaddr_in * client = calloc(1, SOCKET_SIZE); int listenFD; if(ch == NULL){ listenFD = sockfd; }else{ listenFD = (int) hashmap_get( sockets_hmap , ch->port); } /* Non non blocking socket */ printf("rcvMessage: Using NON blocking sockets!\n"); fcntl(listenFD,F_SETFL,socket_flags | O_NONBLOCK); if( (recvfrom(listenFD, &msgSize, sizeof(int), 0, (struct sockaddr *) client, (socklen_t *) &client_len)) == -1){ perror("Error while receiving data"); return NULL; } if(msgSize > 0){ aux = bytestring = calloc(msgSize+sizeof(int), sizeof(char)); printf("<LOG socket_s.c> Server - Message header received OK. Full message size = %d <end>\n", msgSize); if( (recvfrom(listenFD, aux, (msgSize * sizeof(char)) + sizeof(int), 0, (struct sockaddr *) client, (socklen_t *) &client_len)) == -1){ perror("Reading client message failed"); return NULL; }else{ aux+=sizeof(int); msg = deserializeMsg(aux); if(msg->type == CONTACT){ msg->data.socket_client_t.client = client; printf("Tengo client: port - %d\n", client->sin_port); } printf("<LOG socket_s.c> Server - Received message type: %d <end>\n", msg->type); } free(bytestring); } return msg; }
// convert offsets back into ptrs int32_t Msg20Request::deserialize ( ) { return deserializeMsg(sizeof(*this), &size_qbuf, &size_displayMetas, &ptr_qbuf, ((char*)this) + sizeof(*this)); }
bool Msg3a::gotAllSplitReplies ( ) { // if any of the split requests had an error, give up and set m_errno // but don't set if for non critical errors like query truncation if ( m_errno ) { g_errno = m_errno; return true; } // also reset the finalbuf and the oldNumTopDocIds if ( m_finalBuf ) { mfree ( m_finalBuf, m_finalBufSize, "Msg3aF" ); m_finalBuf = NULL; m_finalBufSize = 0; } // update our estimated total hits m_numTotalEstimatedHits = 0; for ( long i = 0; i < m_numHosts ; i++ ) { // get that host that gave us the reply //Host *h = g_hostdb.getHost(i); // . get the reply from multicast // . multicast should have destroyed all slots, but saved reply // . we are responsible for freeing the reply // . we need to call this even if g_errno or m_errno is // set so we can free the replies in Msg3a::reset() // . if we don't call getBestReply() on it multicast should // free it, because Multicast::m_ownReadBuf is still true Multicast *m = &m_mcast[i]; bool freeit = false; long replySize = 0; long replyMaxSize; char *rbuf; Msg39Reply *mr; // . only get it if the reply not already full // . if reply already processed, skip // . perhaps it had no more docids to give us or all termlists // were exhausted on its disk and this is a re-call // . we have to re-process it for count m_numTotalEstHits, etc. rbuf = m->getBestReply ( &replySize , &replyMaxSize , &freeit , true ); //stealIt? // cast it mr = (Msg39Reply *)rbuf; // in case of mem leak, re-label from "mcast" to this so we // can determine where it came from, "Msg3a-GBR" relabel( rbuf, replyMaxSize , "Msg3a-GBR" ); // . we must be able to free it... we must own it // . this is true if we should free it, but we should not have // to free it since it is owned by the slot? if ( freeit ) { log(LOG_LOGIC,"query: msg3a: Steal failed."); char *xx = NULL; *xx=0; } // bad reply? if ( ! mr ) { log(LOG_LOGIC,"query: msg3a: Bad NULL reply."); m_reply [i] = NULL; m_replyMaxSize[i] = 0; // it might have been timd out, just ignore it!! continue; // if size is 0 it can be Msg39 giving us an error! g_errno = EBADREPLYSIZE; m_errno = EBADREPLYSIZE; // all reply buffers should be freed on reset() return true; } // how did this happen? if ( replySize < 29 && ! mr->m_errno ) { // if size is 0 it can be Msg39 giving us an error! g_errno = EBADREPLYSIZE; m_errno = EBADREPLYSIZE; log(LOG_LOGIC,"query: msg3a: Bad reply size of %li.", replySize); // all reply buffers should be freed on reset() return true; } // can this be non-null? we shouldn't be overwriting one // without freeing it... if ( m_reply[i] ) // note the mem leak now log("query: mem leaking a 0x39 reply"); // cast it and set it m_reply [i] = mr; m_replyMaxSize[i] = replyMaxSize; // deserialize it (just sets the ptr_ and size_ member vars) //mr->deserialize ( ); deserializeMsg ( sizeof(Msg39Reply) , &mr->size_docIds, &mr->size_clusterRecs, &mr->ptr_docIds, mr->m_buf ); // sanity check if ( mr->m_nqt != m_q->getNumTerms() ) { g_errno = EBADREPLY; m_errno = EBADREPLY; log("query: msg3a: Split reply qterms=%li != %li.", (long)mr->m_nqt,(long)m_q->getNumTerms() ); return true; } // return if split had an error, but not for a non-critical // error like query truncation if ( mr->m_errno && mr->m_errno != EQUERYTRUNCATED ) { g_errno = mr->m_errno; m_errno = mr->m_errno; log("query: msg3a: Split had error: %s", mstrerror(g_errno)); return true; } // skip down here if reply was already set //skip: // add of the total hits from each split, this is how many // total results the lastest split is estimated to be able to // return // . THIS should now be exact since we read all termlists // of posdb... m_numTotalEstimatedHits += mr->m_estimatedHits; // debug log stuff if ( ! m_debug ) continue; // cast these for printing out long long *docIds = (long long *)mr->ptr_docIds; score_t *scores = (score_t *)mr->ptr_scores; // print out every docid in this split reply for ( long j = 0; j < mr->m_numDocIds ; j++ ) { // print out score_t logf( LOG_DEBUG, "query: msg3a: [%lu] %03li) " "split=%li docId=%012llu domHash=0x%02lx " "score=%lu" , (unsigned long)this , j , i , docIds [j] , (long)g_titledb.getDomHash8FromDocId(docIds[j]), (long)scores[j] ); } } // this seems to always return true! mergeLists ( ); if ( ! m_r->m_useSeoResultsCache ) return true; // now cache the reply SafeBuf cr; long dataSize = 4 + 4 + 4 + m_numDocIds * (8+4+4); long need = sizeof(key_t) + 4 + dataSize; bool status = cr.reserve ( need ); // sanity if ( ( m_ckey.n0 & 0x01 ) == 0x00 ) { char *xx=NULL; *xx=0; } // ignore errors g_errno = 0; // return on error with g_errno cleared if cache add failed if ( ! status ) return true; // add to buf otherwise cr.safeMemcpy ( &m_ckey , sizeof(key_t) ); cr.safeMemcpy ( &dataSize , 4 ); long now = getTimeGlobal(); cr.pushLong ( now ); cr.pushLong ( m_numDocIds ); cr.pushLong ( m_numTotalEstimatedHits );//Results ); long max = m_numDocIds; // then the docids for ( long i = 0 ; i < max ; i++ ) cr.pushLongLong(m_docIds[i] ); for ( long i = 0 ; i < max ; i++ ) cr.pushFloat(m_scores[i]); for ( long i = 0 ; i < max ; i++ ) cr.pushLong(getSiteHash26(i)); // sanity if ( cr.length() != need ) { char *xx=NULL; *xx=0; } // make these key_t startKey; key_t endKey; startKey = m_ckey; // clear delbit startKey.n0 &= 0xfffffffffffffffeLL; // end key is us endKey = m_ckey; // that is the single record m_seoCacheList.set ( cr.getBufStart() , cr.length(), cr.getBufStart(), // alloc cr.getCapacity(), // alloc size (char *)&startKey, (char *)&endKey, -1, // fixeddatasize true, // owndata? false,// use half keys? sizeof(key_t) ); // do not allow cr to free it, msg1 will cr.detachBuf(); // note it //log("seopipe: storing ckey=%s q=%s" // ,KEYSTR(&m_ckey,12) // ,m_r->ptr_query // ); //log("msg1: sending niceness=%li",(long)m_r->m_niceness); // this will often block, but who cares!? it just sends a request off if ( ! m_msg1.addList ( &m_seoCacheList , RDB_SERPDB,//RDB_CACHEDB, m_r->ptr_coll, this, // state gotSerpdbReplyWrapper, // callback false, // forcelocal? m_r->m_niceness ) ) { //log("blocked"); return false; } // we can safely delete m_msg17... just return true return true; }