URIReader optimizations/improvements, support for getHost/getBinHost functions, socket lib improvements + related improvements
This commit is contained in:
parent
4df771eb02
commit
1df76eff16
6 changed files with 70 additions and 42 deletions
|
@ -357,7 +357,7 @@ namespace Comms{
|
|||
dataPage.init(userPageName, 0, false, false);
|
||||
if (!dataPage){
|
||||
std::string host;
|
||||
Socket::hostBytesToStr(ip.data(), 16, host);
|
||||
Socket::hostBytesToStr(ip.data(), ip.size(), host);
|
||||
pid_t thisPid;
|
||||
std::deque<std::string> args;
|
||||
args.push_back(Util::getMyPath() + "MistSession");
|
||||
|
|
|
@ -1221,7 +1221,7 @@ std::string Socket::Connection::getBoundAddress() const{
|
|||
|
||||
/// Gets binary IPv6 address for connection, if available.
|
||||
/// Guaranteed to be either empty or 16 bytes long.
|
||||
std::string Socket::Connection::getBinHost(){
|
||||
std::string Socket::Connection::getBinHost() const{
|
||||
return getIPv6BinAddr(remoteaddr);
|
||||
}
|
||||
|
||||
|
@ -1726,6 +1726,22 @@ void Socket::UDPConnection::setSocketFamily(int AF_TYPE){\
|
|||
family = AF_TYPE;
|
||||
}
|
||||
|
||||
/// Allocates enough space for the largest type of address we support, so that receive calls can write to it.
|
||||
void Socket::UDPConnection::allocateDestination(){
|
||||
if (destAddr && destAddr_size < sizeof(sockaddr_in6)){
|
||||
free(destAddr);
|
||||
destAddr = 0;
|
||||
}
|
||||
if (!destAddr){
|
||||
destAddr = malloc(sizeof(sockaddr_in6));
|
||||
if (destAddr){
|
||||
destAddr_size = sizeof(sockaddr_in6);
|
||||
memset(destAddr, 0, sizeof(sockaddr_in6));
|
||||
((struct sockaddr_in *)destAddr)->sin_family = AF_UNSPEC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Stores the properties of the receiving end of this UDP socket.
|
||||
/// This will be the receiving end for all SendNow calls.
|
||||
void Socket::UDPConnection::SetDestination(std::string destIp, uint32_t port){
|
||||
|
@ -1824,8 +1840,9 @@ void Socket::UDPConnection::GetDestination(std::string &destIp, uint32_t &port){
|
|||
/// Gets the properties of the receiving end of this UDP socket.
|
||||
/// This will be the receiving end for all SendNow calls.
|
||||
std::string Socket::UDPConnection::getBinDestination(){
|
||||
std::string binList = getIPv6BinAddr(*(sockaddr_in6*)destAddr);
|
||||
if (binList.size() < 16){ return std::string("\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", 16); }
|
||||
std::string binList;
|
||||
if (destAddr && destAddr_size){binList = getIPv6BinAddr(*(sockaddr_in6*)destAddr);}
|
||||
if (binList.size() < 16){return std::string("\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", 16);}
|
||||
return binList.substr(0, 16);
|
||||
}// Socket::UDPConnection GetDestination
|
||||
|
||||
|
@ -2081,12 +2098,14 @@ uint16_t Socket::UDPConnection::bind(int port, std::string iface, const std::str
|
|||
bool Socket::UDPConnection::Receive(){
|
||||
if (sock == -1){return false;}
|
||||
data.truncate(0);
|
||||
socklen_t destsize = destAddr_size;
|
||||
int r = recvfrom(sock, data, data.rsize(), MSG_TRUNC | MSG_DONTWAIT, (sockaddr *)destAddr, &destsize);
|
||||
sockaddr_in6 addr;
|
||||
socklen_t destsize = sizeof(addr);
|
||||
int r = recvfrom(sock, data, data.rsize(), MSG_TRUNC | MSG_DONTWAIT, (sockaddr *)&addr, &destsize);
|
||||
if (r == -1){
|
||||
if (errno != EAGAIN){INFO_MSG("UDP receive: %d (%s)", errno, strerror(errno));}
|
||||
return false;
|
||||
}
|
||||
if (destAddr && destsize && destAddr_size >= destsize){memcpy(destAddr, &addr, destsize);}
|
||||
data.append(0, r);
|
||||
down += r;
|
||||
//Handle UDP packets that are too large
|
||||
|
|
|
@ -134,7 +134,7 @@ namespace Socket{
|
|||
void setBlocking(bool blocking); ///< Set this socket to be blocking (true) or nonblocking (false).
|
||||
bool isBlocking(); ///< Check if this socket is blocking (true) or nonblocking (false).
|
||||
std::string getHost() const; ///< Gets hostname for connection, if available.
|
||||
std::string getBinHost();
|
||||
std::string getBinHost() const;
|
||||
void setHost(std::string host); ///< Sets hostname for connection manually.
|
||||
std::string getBoundAddress() const;
|
||||
int getSocket(); ///< Returns internal socket number.
|
||||
|
@ -216,6 +216,7 @@ namespace Socket{
|
|||
int getSock();
|
||||
uint16_t bind(int port, std::string iface = "", const std::string &multicastAddress = "");
|
||||
void setBlocking(bool blocking);
|
||||
void allocateDestination();
|
||||
void SetDestination(std::string hostname, uint32_t port);
|
||||
void GetDestination(std::string &hostname, uint32_t &port);
|
||||
std::string getBinDestination();
|
||||
|
|
|
@ -277,6 +277,16 @@ namespace HTTP{
|
|||
return false;
|
||||
}
|
||||
|
||||
std::string URIReader::getHost() const{
|
||||
if (stateType == HTTP::File){return "";}
|
||||
return downer.getSocket().getHost();
|
||||
}
|
||||
|
||||
std::string URIReader::getBinHost() const{
|
||||
if (stateType == HTTP::File){return std::string("\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", 16);}
|
||||
return downer.getSocket().getBinHost();
|
||||
}
|
||||
|
||||
void URIReader::readAll(size_t (*dataCallback)(const char *data, size_t len)){
|
||||
while (!isEOF()){readSome(dataCallback, 419430);}
|
||||
}
|
||||
|
@ -306,42 +316,37 @@ namespace HTTP{
|
|||
// readsome with callback
|
||||
void URIReader::readSome(size_t wantedLen, Util::DataCallback &cb){
|
||||
if (isEOF()){return;}
|
||||
// Files read from the memory-mapped file
|
||||
if (stateType == HTTP::File){
|
||||
// dataPtr = mapped + curPos;
|
||||
uint64_t dataLen = 0;
|
||||
|
||||
if (wantedLen < totalSize){
|
||||
if ((wantedLen + curPos) > totalSize){
|
||||
dataLen = totalSize - curPos; // restant
|
||||
// INFO_MSG("file curpos: %llu, dataLen: %llu, totalSize: %llu ", curPos, dataLen, totalSize);
|
||||
}else{
|
||||
dataLen = wantedLen;
|
||||
}
|
||||
}else{
|
||||
dataLen = totalSize;
|
||||
}
|
||||
|
||||
std::string t = std::string(mapped + curPos, dataLen);
|
||||
cb.dataCallback(t.c_str(), dataLen);
|
||||
|
||||
// Simple bounds check, don't read beyond the end of the file
|
||||
uint64_t dataLen = ((wantedLen + curPos) > totalSize) ? totalSize - curPos : wantedLen;
|
||||
cb.dataCallback(mapped + curPos, dataLen);
|
||||
curPos += dataLen;
|
||||
|
||||
}else if (stateType == HTTP::HTTP){
|
||||
downer.continueNonBlocking(cb);
|
||||
}else{// streaming mode
|
||||
int s = downer.getSocket().Received().bytes(wantedLen);
|
||||
if (!s){
|
||||
if (downer.getSocket() && downer.getSocket().spool()){
|
||||
s = downer.getSocket().Received().bytes(wantedLen);
|
||||
}else{
|
||||
Util::sleep(50);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Util::ResizeablePointer buf;
|
||||
downer.getSocket().Received().remove(buf, s);
|
||||
cb.dataCallback(buf, s);
|
||||
return;
|
||||
}
|
||||
// HTTP-based read from the Downloader
|
||||
if (stateType == HTTP::HTTP){
|
||||
// Note: this function returns true if the full read was completed only.
|
||||
// It's the reason this function returns void rather than bool.
|
||||
downer.continueNonBlocking(cb);
|
||||
return;
|
||||
}
|
||||
// Everything else uses the socket directly
|
||||
int s = downer.getSocket().Received().bytes(wantedLen);
|
||||
if (!s){
|
||||
// Only attempt to read more if nothing was in the buffer
|
||||
if (downer.getSocket() && downer.getSocket().spool()){
|
||||
s = downer.getSocket().Received().bytes(wantedLen);
|
||||
}else{
|
||||
Util::sleep(50);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Future optimization: augment the Socket::Buffer to handle a Util::DataCallback as argument.
|
||||
// Would remove the need for this extra copy here.
|
||||
Util::ResizeablePointer buf;
|
||||
downer.getSocket().Received().remove(buf, s);
|
||||
cb.dataCallback(buf, s);
|
||||
}
|
||||
|
||||
/// Readsome blocking function.
|
||||
|
|
|
@ -67,6 +67,9 @@ namespace HTTP{
|
|||
|
||||
std::string userAgentOverride;
|
||||
|
||||
std::string getHost() const; ///< Gets hostname for connection, or [::] if local.
|
||||
std::string getBinHost() const; ///< Gets binary form hostname for connection, or [::] if local.
|
||||
|
||||
private:
|
||||
// Internal state variables
|
||||
bool (*cbProgress)(uint8_t); ///< The progress callback, if any. Not called if set to a null pointer.
|
||||
|
|
|
@ -836,7 +836,7 @@ namespace Mist{
|
|||
}
|
||||
|
||||
// this is necessary so that we can get the remote IP when creating STUN replies.
|
||||
udp.SetDestination("0.0.0.0", 4444);
|
||||
udp.allocateDestination();
|
||||
|
||||
// we set parseData to `true` to start the data flow. Is also
|
||||
// used to break out of our loop in `onHTTP()`.
|
||||
|
@ -1153,7 +1153,7 @@ namespace Mist{
|
|||
// function. The `webRTCInputOutputThreadFunc()` is basically empty
|
||||
// and all work for the thread is done here.
|
||||
void OutWebRTC::handleWebRTCInputOutputFromThread(){
|
||||
udp.SetDestination("0.0.0.0", 4444);
|
||||
udp.allocateDestination();
|
||||
while (keepGoing()){
|
||||
if (!handleWebRTCInputOutput()){Util::sleep(20);}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue