Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
RpcServerConn::~RpcServerConn()
{
    RPC_LOG(RPC_LOG_LEV::INFO, "close fd %d", m_fd);
    close(m_fd);
    if (m_rpk != nullptr)
        delete m_rpk;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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);
}
Beispiel #6
0
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;
    }
  }
}
Beispiel #7
0
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;
}
Beispiel #8
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);
	}
}
Beispiel #9
0
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;
}
Beispiel #10
0
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);
	}
}
Beispiel #11
0
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;
}
Beispiel #12
0
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;
}
Beispiel #13
0
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);
}
Beispiel #14
0
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;
}
Beispiel #15
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);

}
Beispiel #16
0
// 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);
}
Beispiel #17
0
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);
}