PkgIOStatus RpcServerConn::sendResponse() { if (!is_connected) { RPC_LOG(RPC_LOG_LEV::WARNING, "send connection already disconnected"); return PkgIOStatus::FAIL; } if (m_sent_pkg != nullptr) { return sendData(); } RespPkgPtr pkg = nullptr; if (m_response_q.pop(pkg, 0)) { m_sent_len = 0; m_sent_pkg = pkg; std::chrono::system_clock::time_point out_q_timepoint = std::chrono::system_clock::now(); RPC_LOG(RPC_LOG_LEV::DEBUG, "resp stay: %d ms", std::chrono::duration_cast<std::chrono::milliseconds>( out_q_timepoint - pkg->gen_time ).count()); auto during = std::chrono::duration_cast<std::chrono::milliseconds>(out_q_timepoint - pkg->gen_time); if( during.count() < 0) { during = during.zero(); } m_server->calcRespQTime(during.count()); RPC_LOG(RPC_LOG_LEV::DEBUG, "will send %d", pkg->data_len); return sendData(); } return PkgIOStatus::NODATA; }
void rpc_set_pagecache_ttl(struct rpc_context *rpc, uint32_t v) { if (v) { RPC_LOG(rpc, 2, "set pagecache ttl to %d seconds\n", v); } else { RPC_LOG(rpc, 2, "set pagecache ttl to infinite"); } rpc->pagecache_ttl = v; }
RpcServerConn::~RpcServerConn() { RPC_LOG(RPC_LOG_LEV::INFO, "close fd %d", m_fd); close(m_fd); if (m_rpk != nullptr) delete m_rpk; }
void rpc_set_pagecache(struct rpc_context *rpc, uint32_t v) { assert(rpc->magic == RPC_CONTEXT_MAGIC); v = MAX(rpc->pagecache, round_to_power_of_two(v)); RPC_LOG(rpc, 2, "pagecache set to %d pages of size %d", v, NFS_BLKSIZE); rpc->pagecache = v; }
bool getHostIp(std::string &str_ip) { char hname[256] = {0}; if( -1 == gethostname(hname, sizeof(hname))) { RPC_LOG(RPC_LOG_LEV::ERROR, "gethostname error %s", strerror(errno)); return false; } return getHostIpByName(str_ip, hname); }
PkgIOStatus RpcServerConn::sendData() { while(1) { int data_to_send = m_sent_pkg->data_len - m_sent_len; int slen = send(m_fd, m_sent_pkg->data + m_sent_len, data_to_send, MSG_NOSIGNAL | MSG_DONTWAIT); //for <= 0 cases if (slen <= 0) { if (slen == 0 || errno == EPIPE) { RPC_LOG(RPC_LOG_LEV::INFO, "peer closed"); return PkgIOStatus::FAIL; } if (errno == EAGAIN) { //ET trigger case //RPC_LOG(RPC_LOG_LEV::INFO, "send data AGAIN"); return PkgIOStatus::PARTIAL; } if( errno == EINTR) { continue; } else { RPC_LOG(RPC_LOG_LEV::ERROR, "send data error! %s", strerror(errno)); return PkgIOStatus::FAIL; } } //for > 0 case m_sent_len += slen; if (m_sent_pkg->data_len == m_sent_len) { RPC_LOG(RPC_LOG_LEV::DEBUG, "full send %d", m_sent_len); m_sent_pkg = nullptr; m_sent_len = 0; return PkgIOStatus::FULL; } else { RPC_LOG(RPC_LOG_LEV::DEBUG, "left send %d", m_sent_pkg->data_len - m_sent_len); //NOTICE:consider as EAGAIN return PkgIOStatus::PARTIAL; } } }
int headers_complete_cb (http_parser *p) { RpcServerHttpConn *httpconn = (RpcServerHttpConn *)p->data; if(p->method == HTTP_GET) { httpconn->bodyFinal(true); } if(p->method == HTTP_POST && p->content_length == 0) { RPC_LOG(RPC_LOG_LEV::WARNING, "not support content_length 0"); httpconn->setFail(true); } httpconn->setKeepAlive(http_should_keep_alive(p)); return 0; }
void rpc_set_readahead(struct rpc_context *rpc, uint32_t v) { uint32_t min_pagecache; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (v) { v = MAX(NFS_BLKSIZE, round_to_power_of_two(v)); } RPC_LOG(rpc, 2, "readahead set to %d byte", v); rpc->readahead = v; min_pagecache = (2 * v) / NFS_BLKSIZE; if (rpc->pagecache < min_pagecache) { /* current pagecache implementation needs a pagecache bigger * than the readahead size to avoid collisions */ rpc_set_pagecache(rpc, min_pagecache); } }
bool getHostIpByName(std::string &str_ip, const char *hname) { struct hostent *hent; hent = gethostbyname(hname); if(hent == nullptr) { RPC_LOG(RPC_LOG_LEV::ERROR, "gethostbyname error %s", strerror(errno)); return false; } //RPC_LOG(RPC_LOG_LEV::DEBUG, "hostname: %s/naddress list: ", hent->h_name); //get first hostname ip char *c_ip = inet_ntoa(*(struct in_addr*)(hent->h_addr_list[0])); if(c_ip != nullptr) { str_ip.assign(c_ip); return true; } return false; }
void rpc_set_error(struct rpc_context *rpc, const char *error_string, ...) { va_list ap; char *old_error_string = rpc->error_string; assert(rpc->magic == RPC_CONTEXT_MAGIC); va_start(ap, error_string); rpc->error_string = malloc(1024); vsnprintf(rpc->error_string, 1024, error_string, ap); va_end(ap); RPC_LOG(rpc, 1, "error: %s", rpc->error_string); if (old_error_string != NULL) { free(old_error_string); } }
bool getHostIpByName(std::string &str_ip, const char *hname) { int len = 1024; char *buf = (char *)malloc(len); if(buf == nullptr) { return false; } int rc, err; struct hostent hbuf; struct hostent *result; while ((rc = gethostbyname_r(hname, &hbuf, buf, len, &result, &err)) == ERANGE) { /* expand buf */ len *= 2; char *tmp = (char *)realloc(buf, len); if (nullptr == tmp) { free(buf); return false; }else{ buf = tmp; } } if (0 != rc || nullptr == result) { RPC_LOG(RPC_LOG_LEV::ERROR, "gethostbyname error %s", strerror(errno)); free(buf); return false; } //RPC_LOG(RPC_LOG_LEV::DEBUG, "hostname: %s/naddress list: ", result->h_name); //get first hostname ip char *c_ip = inet_ntoa(*(struct in_addr*)(result->h_addr_list[0])); if(c_ip != nullptr) { str_ip.assign(c_ip); free(buf); return true; } free(buf); return false; }
int CDVD_findfile(char* fname, struct TocEntry* tocEntry){ static char filename[128+1]; static char pathname[1024+1]; static char toc[2048]; char* dirname; static struct TocEntry localTocEntry; // used for internal checking only int found_dir; int num_dir_sectors; int current_sector; int dir_lba; struct dirTocEntry* tocEntryPointer; #ifdef DEBUG printf("CDVD_findfile called\n"); #endif //make sure we have good cdReadMode cdReadMode.trycount = 0; cdReadMode.spindlctrl = CdSpinStm; cdReadMode.datapattern = CdSecS2048; _splitpath2(fname, pathname, filename); // Find the TOC for a specific directory if (CDVD_GetVolumeDescriptor() != TRUE){ #ifdef RPC_LOG RPC_LOG("Could not get CD Volume Descriptor\n"); #endif return -1; } // Read the TOC of the root directory if (CdRead(CDVolDesc.rootToc.tocLBA,1,toc,&cdReadMode) != TRUE){ #ifdef RPC_LOG RPC_LOG("Couldn't Read from CD !\n"); #endif return -1; } //CdSync(0x00); // point the tocEntryPointer at the first real toc entry (char*)tocEntryPointer = toc; num_dir_sectors = (tocEntryPointer->fileSize+2047) >> 11; //round up fix current_sector = tocEntryPointer->fileLBA; (char*)tocEntryPointer += tocEntryPointer->length; (char*)tocEntryPointer += tocEntryPointer->length; localTocEntry.fileLBA = CDVolDesc.rootToc.tocLBA; // while (there are more dir names in the path) dirname = strtok( pathname, "\\/" ); while( dirname != NULL ) { found_dir = FALSE; /* while(tocEntryPointer->length > 0) { // while there are still more directory entries then search through // for the one we want if (tocEntryPointer->fileProperties & 0x02) { // Copy the CD format TOC Entry to our format TocEntryCopy(&localTocEntry, tocEntryPointer); // If this TOC Entry is a directory, // then see if it has the right name if (strcasecmp(dirname,localTocEntry.filename) == 0) { // if the name matches then we've found the directory found_dir = TRUE; break; } } // point to the next entry (char*)tocEntryPointer += tocEntryPointer->length; } */ while(1) { if ((tocEntryPointer->length == 0) || (((char*)tocEntryPointer-toc)>=2048)) { num_dir_sectors--; if (num_dir_sectors > 0) { // If we've run out of entries, but arent on the last sector // then load another sector current_sector++; if (CdRead(current_sector,1,toc,&cdReadMode) != TRUE) { return -1; } // CdSync(0x00); (char*)tocEntryPointer = toc; } else { // Couldnt find the directory, and got to end of directory return -1; } } if (tocEntryPointer->fileProperties & 0x02) { TocEntryCopy(&localTocEntry, tocEntryPointer); // If this TOC Entry is a directory, // then see if it has the right name if (strcmp(dirname,localTocEntry.filename) == 0) { // if the name matches then we've found the directory found_dir = TRUE; break; } } // point to the next entry (char*)tocEntryPointer += tocEntryPointer->length; } // If we havent found the directory name we wanted then fail if (found_dir != TRUE) { return -1; } // Get next directory name dirname = strtok( NULL, "\\/" ); // Read the TOC of the found subdirectory if (CdRead(localTocEntry.fileLBA,1,toc,&cdReadMode) != TRUE) { return -1; } // CdSync(0x00); num_dir_sectors = (localTocEntry.fileSize+2047) >> 11; //round up fix current_sector = localTocEntry.fileLBA; // and point the tocEntryPointer at the first real toc entry (char*)tocEntryPointer = toc; (char*)tocEntryPointer += tocEntryPointer->length; (char*)tocEntryPointer += tocEntryPointer->length; } (char*)tocEntryPointer = toc; num_dir_sectors = (tocEntryPointer->fileSize+2047) >> 11; //round up fix dir_lba = tocEntryPointer->fileLBA; (char*)tocEntryPointer = toc; (char*)tocEntryPointer += tocEntryPointer->length; (char*)tocEntryPointer += tocEntryPointer->length; while (num_dir_sectors > 0) { while(tocEntryPointer->length != 0) { // Copy the CD format TOC Entry to our format TocEntryCopy(&localTocEntry, tocEntryPointer); if ((strnicmp(localTocEntry.filename, filename, strlen(filename)) == 0) || ((filename[strlen(filename)-2] == ';') && (localTocEntry.filename[strlen(localTocEntry.filename)-2] == ';') && (strnicmp(localTocEntry.filename, filename, strlen(filename)-2) == 0))) { // if the filename matches then copy the toc Entry tocEntry->fileLBA = localTocEntry.fileLBA; tocEntry->fileProperties = localTocEntry.fileProperties; tocEntry->fileSize = localTocEntry.fileSize; strcpy(tocEntry->filename, localTocEntry.filename); memcpy(tocEntry->date, localTocEntry.date, 7); #ifdef DEBUG printf("CDVD_findfile: found file\n"); #endif return TRUE; } (char*)tocEntryPointer += tocEntryPointer->length; } num_dir_sectors--; if (num_dir_sectors > 0) { dir_lba++; if (CdRead(dir_lba,1,toc,&cdReadMode) != TRUE){ return -1; } // CdSync(0x00); (char*)tocEntryPointer = toc; } } return FALSE; }
void RpcWorker::run(std::shared_ptr<request_pkg> pkg) { auto during = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - pkg->gen_time); if (during.count() < 0) { during = during.zero(); } m_server->calcReqQTime(during.count()); uint32_t proto_len = ntohl(*((uint32_t *)pkg->data)); //must get request id from here RpcInnerReq req; if (!req.ParseFromArray(pkg->data + sizeof(proto_len), proto_len)) { RPC_LOG(RPC_LOG_LEV::ERROR, "parse internal pkg fail %s", req.DebugString().c_str()); return; } RawData rd; if(req.has_data()) { rd.data = (char *)req.data().data(); rd.data_len = req.data().size(); } else { rd.data = pkg->data + sizeof(proto_len); rd.data_len = pkg->data_len - sizeof(proto_len) - proto_len; } RpcServerConnWorker *connworker = pkg->conn_worker; if(connworker == nullptr) { RPC_LOG(RPC_LOG_LEV::ERROR, "connworker is null, %s %s", req.method_name().c_str(), req.request_id().c_str()); return; } RPC_LOG(RPC_LOG_LEV::DEBUG, "req %s:%s stay in queue: %d ms", req.request_id().c_str(), req.method_name().c_str(), during.count()); IRpcRespBrokerPtr rpcbroker = std::make_shared<RpcRespBroker>(connworker, pkg->connection_id, req.request_id(), (req.type() == RpcInnerReq::TWO_WAY), pkg->is_from_http); if(m_srvmap.find(req.service_name()) == m_srvmap.end()) { rpcbroker->setReturnVal(RpcStatus::RPC_SRV_NOTFOUND); RPC_LOG(RPC_LOG_LEV::WARNING, "Unknow service request #%s#", req.service_name().c_str()); pushResponse(rpcbroker, pkg->connection_id, req.type(), connworker); return; } IService *p_service = m_srvmap[req.service_name()].pSrv; if (pkg->is_from_http && !p_service->m_impl->is_method_allow_http(req.method_name())) { RPC_LOG(RPC_LOG_LEV::WARNING, "Not allowed request: %s", req.method_name().c_str()); rpcbroker->setReturnVal(RpcStatus::RPC_METHOD_NOTFOUND); pushResponse(rpcbroker, pkg->connection_id, req.type(), connworker); return; } if (p_service != nullptr) { std::chrono::system_clock::time_point begin_call_timepoint = std::chrono::system_clock::now(); RpcMethodStatusPtr method_status = nullptr; RpcStatus ret = p_service->m_impl->runMethod(req.method_name(), rd, rpcbroker, method_status); during = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - begin_call_timepoint); if(method_status) { if (during.count() < 0) { during = during.zero(); } m_server->calcCallTime(during.count()); method_status->calcCallTime(during.count()); RPC_LOG(RPC_LOG_LEV::DEBUG, "%s call take: %llu ms", req.method_name().c_str(), during.count()); auto timeout_during = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - pkg->gen_time); if (req.timeout() > 0 && timeout_during.count() > req.timeout() + 3) { ++(method_status->timeout_call_nums); RPC_LOG(RPC_LOG_LEV::WARNING, "req %s:%s should already timeout on client %d->%d, will not response", req.request_id().c_str(), req.method_name().c_str(), timeout_during.count(), req.timeout() + 3); return; } } switch (ret) { case RpcStatus::RPC_SERVER_OK: rpcbroker->setReturnVal(ret); //TODO:if broker already call response, continue loop here if(rpcbroker->isResponed()) { return; } break; case RpcStatus::RPC_METHOD_NOTFOUND: rpcbroker->setReturnVal(ret); RPC_LOG(RPC_LOG_LEV::WARNING, "Unknow method request #%s#", req.method_name().c_str()); break; case RpcStatus::RPC_SERVER_FAIL: rpcbroker->setReturnVal(ret); RPC_LOG(RPC_LOG_LEV::WARNING, "method call fail #%s#", req.method_name().c_str()); break; case RpcStatus::RPC_SERVER_NONE: return; break; default: break; } } pushResponse(rpcbroker, pkg->connection_id, req.type(), connworker); }
int rpc_service(struct rpc_context *rpc, int revents) { assert(rpc->magic == RPC_CONTEXT_MAGIC); if (revents & POLLERR) { #ifdef WIN32 char err = 0; #else int err = 0; #endif socklen_t err_size = sizeof(err); if (getsockopt(rpc->fd, SOL_SOCKET, SO_ERROR, (char *)&err, &err_size) != 0 || err != 0) { if (err == 0) { err = errno; } rpc_set_error(rpc, "rpc_service: socket error " "%s(%d).", strerror(err), err); } else { rpc_set_error(rpc, "rpc_service: POLLERR, " "Unknown socket error."); } if (rpc->connect_cb != NULL) { rpc->connect_cb(rpc, RPC_STATUS_ERROR, rpc->error_string, rpc->connect_data); } return -1; } if (revents & POLLHUP) { rpc_set_error(rpc, "Socket failed with POLLHUP"); if (rpc->connect_cb != NULL) { rpc->connect_cb(rpc, RPC_STATUS_ERROR, rpc->error_string, rpc->connect_data); } return -1; } if (rpc->is_connected == 0 && rpc->fd != -1 && revents&POLLOUT) { int err = 0; socklen_t err_size = sizeof(err); if (getsockopt(rpc->fd, SOL_SOCKET, SO_ERROR, (char *)&err, &err_size) != 0 || err != 0) { if (err == 0) { err = errno; } rpc_set_error(rpc, "rpc_service: socket error " "%s(%d) while connecting.", strerror(err), err); if (rpc->connect_cb != NULL) { rpc->connect_cb(rpc, RPC_STATUS_ERROR, NULL, rpc->connect_data); } return -1; } rpc->is_connected = 1; RPC_LOG(rpc, 2, "connection established"); if (rpc->connect_cb != NULL) { rpc->connect_cb(rpc, RPC_STATUS_SUCCESS, NULL, rpc->connect_data); } return 0; } if (revents & POLLIN) { if (rpc_read_from_socket(rpc) != 0) { rpc_reconnect_requeue(rpc); return 0; } } if (revents & POLLOUT && rpc_has_queue(&rpc->outqueue)) { if (rpc_write_to_socket(rpc) != 0) { rpc_set_error(rpc, "write to socket failed"); return -1; } } return 0; }
// This is the RPC-ready function which takes the request to start the tocEntry retrieval int CDVD_GetDir_RPC_request(char* pathname, char* extensions, unsigned int inc_dirs){ // int dir_depth = 1; static char toc[2048]; char* dirname; int found_dir; int num_dir_sectors; unsigned int toc_entry_num; struct dirTocEntry* tocEntryPointer; static struct TocEntry localTocEntry; int current_sector; // store the extension list statically for the retrieve function strncpy(getDirTocData.extension_list, extensions, 128); getDirTocData.extension_list[128]=0; getDirTocData.inc_dirs = inc_dirs; // Find the TOC for a specific directory if (CDVD_GetVolumeDescriptor() != TRUE){ #ifdef RPC_LOG RPC_LOG("[RPC:cdvd] Could not get CD Volume Descriptor\n"); #endif return -1; } #ifdef RPC_LOG RPC_LOG("[RPC:cdvd] Getting Directory Listing for: \"%s\"\n", pathname); #endif // Read the TOC of the root directory if (CdRead(CDVolDesc.rootToc.tocLBA,1,toc,&cdReadMode) != TRUE){ #ifdef RPC_LOG RPC_LOG("[RPC: ] Couldn't Read from CD !\n"); #endif return -1; } //CdSync(0x00); // point the tocEntryPointer at the first real toc entry (char*)tocEntryPointer = toc; num_dir_sectors = (tocEntryPointer->fileSize+2047) >> 11; current_sector = tocEntryPointer->fileLBA; (char*)tocEntryPointer += tocEntryPointer->length; (char*)tocEntryPointer += tocEntryPointer->length; // use strtok to get the next dir name // if there isnt one, then assume we want the LBA // for the current one, and exit the while loop // if there is another dir name then increment dir_depth // and look through dir table entries until we find the right name // if we dont find the right name // before finding an entry at a higher level (lower num), then return nothing localTocEntry.fileLBA = CDVolDesc.rootToc.tocLBA; // while (there are more dir names in the path) dirname = strtok( pathname, "\\/" ); while( dirname != NULL ){ found_dir = FALSE; while(1){ if ((tocEntryPointer->length == 0) || (((char*)tocEntryPointer-toc)>=2048)) { num_dir_sectors--; if (num_dir_sectors > 0){ // If we've run out of entries, but arent on the last sector // then load another sector current_sector++; if (CdRead(current_sector,1,toc,&cdReadMode) != TRUE){ #ifdef RPC_LOG RPC_LOG("[RPC: ] Couldn't Read from CD !\n"); #endif return -1; } //CdSync(0x00); (char*)tocEntryPointer = toc; } else{ // Couldnt find the directory, and got to end of directory return -1; } } if (tocEntryPointer->fileProperties & 0x02){ TocEntryCopy(&localTocEntry, tocEntryPointer); // If this TOC Entry is a directory, // then see if it has the right name if (strcmp(dirname,localTocEntry.filename) == 0){ // if the name matches then we've found the directory found_dir = TRUE; #ifdef RPC_LOG RPC_LOG("[RPC: ] Found directory %s in subdir at sector %d\n",dirname,current_sector); RPC_LOG("[RPC: ] LBA of found subdirectory = %d\n",localTocEntry.fileLBA); #endif break; } } // point to the next entry (char*)tocEntryPointer += tocEntryPointer->length; } // If we havent found the directory name we wanted then fail if (found_dir != TRUE) return -1; // Get next directory name dirname = strtok( NULL, "\\/" ); // Read the TOC of the found subdirectory if (CdRead(localTocEntry.fileLBA,1,toc,&cdReadMode) != TRUE){ #ifdef RPC_LOG RPC_LOG("[RPC: ] Couldn't Read from CD !\n"); #endif return -1; } //CdSync(0x00); num_dir_sectors = (localTocEntry.fileSize+2047) >> 11; current_sector = localTocEntry.fileLBA; // and point the tocEntryPointer at the first real toc entry (char*)tocEntryPointer = toc; (char*)tocEntryPointer += tocEntryPointer->length; (char*)tocEntryPointer += tocEntryPointer->length; } // We know how much data we need to read in from the DirTocHeader // but we need to read in at least 1 sector before we can get this value // Now we need to COUNT the number of entries (dont do anything with info at this point) // so set the tocEntryPointer to point to the first actual file entry // This is a bit of a waste of reads since we're not actually copying the data out yet, // but we dont know how big this TOC might be, so we cant allocate a specific size (char*)tocEntryPointer = toc; // Need to STORE the start LBA and number of Sectors, for use by the retrieve func. getDirTocData.start_LBA = localTocEntry.fileLBA; getDirTocData.num_sectors = (tocEntryPointer->fileSize+2047) >> 11; getDirTocData.num_entries = 0; getDirTocData.current_entry = 0; getDirTocData.current_sector = getDirTocData.start_LBA; getDirTocData.current_sector_offset = 0; num_dir_sectors = getDirTocData.num_sectors; (char*)tocEntryPointer = toc; (char*)tocEntryPointer += tocEntryPointer->length; (char*)tocEntryPointer += tocEntryPointer->length; toc_entry_num=0; while(1){ if ((tocEntryPointer->length == 0) || (((char*)tocEntryPointer-toc)>=2048)){ // decrease the number of dirs remaining num_dir_sectors--; if (num_dir_sectors > 0){ // If we've run out of entries, but arent on the last sector // then load another sector getDirTocData.current_sector++; if (CdRead(getDirTocData.current_sector,1,toc,&cdReadMode) != TRUE){ #ifdef RPC_LOG RPC_LOG("[RPC: ] Couldn't Read from CD !\n"); #endif return -1; } //CdSync(0x00); (char*)tocEntryPointer = toc; // continue; } else{ getDirTocData.num_entries = toc_entry_num; getDirTocData.current_sector = getDirTocData.start_LBA; return (toc_entry_num); } } // We've found a file/dir in this directory // now check if it matches our extension list (if there is one) TocEntryCopy(&localTocEntry, tocEntryPointer); if (localTocEntry.fileProperties & 0x02){ // If this is a subdir, then check if we want to include subdirs if (getDirTocData.inc_dirs){ toc_entry_num++; } } else{ if (strlen(getDirTocData.extension_list) > 0){ if (TocEntryCompare(localTocEntry.filename, getDirTocData.extension_list) == TRUE){ // increment the number of matching entries counter toc_entry_num++; } } else{ toc_entry_num++; } } (char*)tocEntryPointer += tocEntryPointer->length; } // THIS SHOULD BE UNREACHABLE - // since we are trying to count ALL matching entries, rather than upto a limit // STORE total number of TOC entries getDirTocData.num_entries = toc_entry_num; getDirTocData.current_sector = getDirTocData.start_LBA; // we've reached the toc entry limit, so return how many we've done return (toc_entry_num); }
// This function can be called repeatedly after CDVD_GetDir_RPC_request to get the actual entries // buffer (tocEntry) must be 18KB in size, and this will be filled with a maximum of 128 entries in one go int CDVD_GetDir_RPC_get_entries(struct TocEntry tocEntry[], int req_entries){ static char toc[2048]; int toc_entry_num; struct dirTocEntry* tocEntryPointer; if (CdRead(getDirTocData.current_sector,1,toc,&cdReadMode) != TRUE){ #ifdef RPC_LOG RPC_LOG("[RPC:cdvd] Couldn't Read from CD !\n"); #endif return -1; } //CdSync(0x00); if (getDirTocData.current_entry == 0){ // if this is the first read then make sure we point to the first real entry (char*)tocEntryPointer = toc; (char*)tocEntryPointer += tocEntryPointer->length; (char*)tocEntryPointer += tocEntryPointer->length; getDirTocData.current_sector_offset = (char*)tocEntryPointer - toc; } else{ (char*)tocEntryPointer = toc + getDirTocData.current_sector_offset; } if (req_entries > 128) req_entries = 128; for (toc_entry_num=0; toc_entry_num < req_entries;){ if ((tocEntryPointer->length == 0) || (getDirTocData.current_sector_offset >= 2048)){ // decrease the number of dirs remaining getDirTocData.num_sectors--; if (getDirTocData.num_sectors > 0){ // If we've run out of entries, but arent on the last sector // then load another sector getDirTocData.current_sector++; if (CdRead(getDirTocData.current_sector,1,toc,&cdReadMode) != TRUE){ #ifdef RPC_LOG RPC_LOG("[RPC:cdvd] Couldn't Read from CD !\n"); #endif return -1; } //CdSync(0x00); getDirTocData.current_sector_offset = 0; (char*)tocEntryPointer = toc + getDirTocData.current_sector_offset; // continue; } else{ return (toc_entry_num); } } // This must be incremented even if the filename doesnt match extension list getDirTocData.current_entry++; // We've found a file in this directory // now check if it matches our extension list (if there is one) // Copy the entry regardless, as it makes the comparison easier // if it doesn't match then it will just be overwritten TocEntryCopy(&tocEntry[toc_entry_num], tocEntryPointer); if (tocEntry[toc_entry_num].fileProperties & 0x02){ // If this is a subdir, then check if we want to include subdirs if (getDirTocData.inc_dirs) { toc_entry_num++; } getDirTocData.current_sector_offset += tocEntryPointer->length; (char*)tocEntryPointer = toc + getDirTocData.current_sector_offset; } else{ if (strlen(getDirTocData.extension_list) > 0){ if (TocEntryCompare(tocEntry[toc_entry_num].filename, getDirTocData.extension_list) == TRUE){ // increment the number of matching entries counter toc_entry_num++; } getDirTocData.current_sector_offset += tocEntryPointer->length; (char*)tocEntryPointer = toc + getDirTocData.current_sector_offset; } else{ toc_entry_num++; getDirTocData.current_sector_offset += tocEntryPointer->length; (char*)tocEntryPointer = toc + getDirTocData.current_sector_offset; } } /* if (strlen(getDirTocData.extension_list) > 0) { if (TocEntryCompare(tocEntry[toc_entry_num].filename, getDirTocData.extension_list) == TRUE) { // increment this here, rather than in the main for loop // since this should count the number of matching entries toc_entry_num++; } getDirTocData.current_sector_offset += tocEntryPointer->length; (char*)tocEntryPointer = toc + getDirTocData.current_sector_offset; } else { toc_entry_num++; getDirTocData.current_sector_offset += tocEntryPointer->length; (char*)tocEntryPointer = toc + getDirTocData.current_sector_offset; } */ } return (toc_entry_num); }
pkg_ret_t RpcServerHttpConn::getRequest() { if (!is_connected) { RPC_LOG(RPC_LOG_LEV::WARNING, "connection already disconnected"); return pkg_ret_t(-1, nullptr); } while(1) { char data[4096]; errno = 0; int rsize = recv(m_fd, data, sizeof(data), 0); if (rsize < 0) { if( errno == EAGAIN || errno == EINTR) { //ET trigger case //will continue until we read the full package length RPC_LOG(RPC_LOG_LEV::DEBUG, "socket EAGAIN"); return pkg_ret_t(0, nullptr); } else { RPC_LOG(RPC_LOG_LEV::ERROR, "try recv pkg len error %s, need recv %d:%d", strerror(errno), rsize, sizeof(data)); return pkg_ret_t(-1, nullptr); } } else { printf("http %s\n", data); int nparsed = http_parser_execute(m_http_parser, &m_setting, data, rsize); if (m_http_parser->upgrade) { /* handle new protocol */ RPC_LOG(RPC_LOG_LEV::INFO, "can't handle upgrade"); return pkg_ret_t(-1, nullptr); } else if (nparsed != rsize) { /* Handle error. Usually just close the connection. */ RPC_LOG(RPC_LOG_LEV::INFO, "parser Peer disconected"); return pkg_ret_t(-1, nullptr); } if (rsize == 0) { RPC_LOG(RPC_LOG_LEV::INFO, "Peer disconected"); return pkg_ret_t(-1, nullptr); } if(m_parse_fail) { RPC_LOG(RPC_LOG_LEV::WARNING, "parse fail"); return pkg_ret_t(-1, nullptr); } if(m_is_body_final) { m_is_body_final = false; RPC_LOG(RPC_LOG_LEV::WARNING, "get compelete http req, url:%s", m_url.c_str()); std::string::size_type service_pos = m_url.find('/', 1); std::string service_name = m_url.substr(1, service_pos - 1); std::string method_name = m_url.substr(service_pos + 1, m_url.size()); RpcInnerReq req; req.set_version(1); req.set_type(RpcInnerReq::TWO_WAY); req.set_request_id("http"); req.set_service_name(service_name); req.set_method_name(method_name); req.set_data(m_body); req.set_timeout(0); uint32_t proto_len = req.ByteSize(); uint32_t proto_hdr = htonl(proto_len); auto reqpkg = std::make_shared<request_pkg>(proto_len + sizeof(proto_len), m_seqid); reqpkg->is_from_http = true; memcpy(reqpkg->data, &proto_hdr, sizeof(proto_hdr)); if (!req.SerializeToArray(reqpkg->data + sizeof(proto_hdr), proto_len)) { RPC_LOG(RPC_LOG_LEV::ERROR, "Serialize req data fail"); return pkg_ret_t(-1, nullptr); } reqpkg->data_len = proto_len; return pkg_ret_t(0, reqpkg); } else { return pkg_ret_t(0, nullptr); } } } return pkg_ret_t(-1, nullptr); }