Ejemplo n.º 1
0
void *waiting(void *data)
{
	// Variables
	UserConnection *connection = NULL;
	char readingBuffer[MAX_PACKAGE_SIZE];
	ssize_t status;
	
	// Init
	connection = (UserConnection *)data;
	
	// Wait
	while(1)
	{
		status = connection->readFromStream(readingBuffer);
		if(status == -1) // Error
		{
			perror("Reading from client");
			delete connection;
			_exit(1);
		}
		else if(status == 0) // Connection broke
		{
			puts("User disconnected");
			delete connection;
			_exit(0);
		}
		printf("Read: %s\n", readingBuffer);
	}
}
Ejemplo n.º 2
0
/**
 * Someone's connecting, accept the connection and wait for identification...
 * It's always the other fellow that starts sending if he made the connection.
 */
void ConnectionManager::accept(const Socket& sock, bool secure) throw() {
    uint32_t now = GET_TICK();

    if(now > floodCounter) {
        floodCounter = now + FLOOD_ADD;
    } else {
        if(false && now + FLOOD_TRIGGER < floodCounter) {
            Socket s;
            try {
                s.accept(sock);
            } catch(const SocketException&) {
                // ...
            }
            dcdebug("Connection flood detected!\n");
            return;
        } else {
            floodCounter += FLOOD_ADD;
        }
    }
    UserConnection* uc = getConnection(false, secure);
    uc->setFlag(UserConnection::FLAG_INCOMING);
    uc->setState(UserConnection::STATE_SUPNICK);
    uc->setLastActivity(GET_TICK());
    try {
        uc->accept(sock);
    } catch(const Exception&) {
        putConnection(uc);
        delete uc;
    }
}
Ejemplo n.º 3
0
Download::Download(UserConnection& conn, QueueItem& qi, const string& path, bool supportsTrees) throw() : Transfer(conn, path, qi.getTTH()),
	tempTarget(qi.getTempTarget()), file(0), treeValid(false)
{
	conn.setDownload(this);

	if(qi.isSet(QueueItem::FLAG_PARTIAL_LIST)) {
		setType(TYPE_PARTIAL_LIST);
	} else if(qi.isSet(QueueItem::FLAG_USER_LIST)) {
		setType(TYPE_FULL_LIST);
	}

	if(qi.getSize() != -1) {
		if(HashManager::getInstance()->getTree(getTTH(), getTigerTree())) {
			setTreeValid(true);
			setSegment(qi.getNextSegment(getTigerTree().getBlockSize(), conn.getChunkSize()));
		} else if(supportsTrees && !qi.getSource(conn.getUser())->isSet(QueueItem::Source::FLAG_NO_TREE) && qi.getSize() > HashManager::MIN_BLOCK_SIZE) {
			// Get the tree unless the file is small (for small files, we'd probably only get the root anyway)
			setType(TYPE_TREE);
			getTigerTree().setFileSize(qi.getSize());
			setSegment(Segment(0, -1));
		} else {
			// Use the root as tree to get some sort of validation at least...
			getTigerTree() = TigerTree(qi.getSize(), qi.getSize(), getTTH());
			setTreeValid(true);
			setSegment(qi.getNextSegment(getTigerTree().getBlockSize(), 0));
		}
	}
}
/**
 * Someone's connecting, accept the connection and wait for identification...
 * It's always the other fellow that starts sending if he made the connection.
 */
void ConnectionManager::on(ServerSocketListener::IncomingConnection) throw() {
	UserConnection* uc = NULL;
	u_int32_t now = GET_TICK();

	if(now > floodCounter) {
		floodCounter = now + FLOOD_ADD;
	} else {
		if(now + FLOOD_TRIGGER < floodCounter) {
			Socket s;
			try {
				s.accept(socket);
			} catch(const SocketException&) {
				// ...
			}
			dcdebug("Connection flood detected!\n");
			return;
		} else {
			floodCounter += 2000;
		}
	}

	try { 
		uc = getConnection();
		uc->setFlag(UserConnection::FLAG_INCOMING);
		uc->setState(UserConnection::STATE_NICK);
		uc->setLastActivity(GET_TICK());
		uc->accept(socket);
	} catch(const SocketException& e) {
		dcdebug("ConnectionManager::OnIncomingConnection caught: %s\n", e.getError().c_str());
		if(uc)
			putConnection(uc);
	}
}
Ejemplo n.º 5
0
void ConnectionManager::disconnect(const User::Ptr& aUser, int isDownload) {
    Lock l(cs);
    for(UserConnection::Iter i = userConnections.begin(); i != userConnections.end(); ++i) {
        UserConnection* uc = *i;
        if(uc->getUser() == aUser && uc->isSet(isDownload ? UserConnection::FLAG_DOWNLOAD : UserConnection::FLAG_UPLOAD)) {
            uc->disconnect(true);
            break;
        }
    }
}
Ejemplo n.º 6
0
void UploadManager::addFailedUpload(const UserConnection& source, string filename) {
	{
		Lock l(cs);
		if (!count_if(waitingUsers.begin(), waitingUsers.end(), CompareFirst<User::Ptr, uint32_t>(source.getUser())))
			waitingUsers.push_back(WaitingUser(source.getUser(), GET_TICK()));
		waitingFiles[source.getUser()].insert(filename);		//files for which user's asked
	}

	fire(UploadManagerListener::WaitingAddFile(), source.getUser(), filename);
}
Ejemplo n.º 7
0
void DownloadManager::checkIdle(const UserPtr& user) {
    Lock l(cs);
    for(UserConnectionList::iterator i = idlers.begin(); i != idlers.end(); ++i) {
        UserConnection* uc = *i;
        if(uc->getUser() == user) {
            uc->updated();
            return;
        }
    }
}
Ejemplo n.º 8
0
UserConnection* ConnectionManager::getConnection(bool aNmdc, bool secure) throw() {
    UserConnection* uc = new UserConnection(secure);
    uc->addListener(this);
    {
        Lock l(cs);
        userConnections.push_back(uc);
    }
    if(aNmdc)
        uc->setFlag(UserConnection::FLAG_NMDC);
    return uc;
}
void usubRequest::operator()(const SubscriptionLib::UsubRequest& req){
	  UserConnection * user = Users::getInstance()->getUser(req.getLogin());
	  Subscription * subs = SubList::getInstance()->getSubscription(req.getSubId());
	  if(user!=NULL && subs!=NULL &&socket_==user->getsocket() && user->isContainsSubject(subs)){
	      		user->removeSubject(subs);
	      		subs->removeObserver(user);
	      		SubscriptionLib::UsubResponse response(0, std::string("USubs operation was succeed"));
	      		MsgSender::deliver(response, user->getsocket());
	  }else{;
		  SubscriptionLib::UsubResponse response(1, std::string("User is not authorized |subscription with specified id is not exist | user is not subscribe this subscription"));
		  MsgSender::deliver(response, socket_);
	  }
}
void ConnectionManager::connect(const string& aServer, short aPort, const string& aNick) {
	if(shuttingDown)
		return;

	UserConnection* uc = NULL;
	try {
		uc = getConnection();
		uc->setNick(aNick);
		uc->setState(UserConnection::STATE_CONNECT);
		uc->connect(aServer, aPort);
	} catch(const SocketException&) {
		if(uc)
			putConnection(uc);
	}
}
Ejemplo n.º 11
0
void Transfer::getParams(const UserConnection& aSource, StringMap& params) {
	params["userNI"] = aSource.getUser()->getNick();
	params["userI4"] = aSource.getRemoteIp();
	params["hub"] = aSource.getUser()->getClientName();
	params["hubURL"] = aSource.getUser()->getClientUrl();
	params["fileSI"] = Util::toString(getSize());
	params["fileSIshort"] = Util::formatBytes(getSize());
	params["fileSIchunk"] = Util::toString(getTotal());
	params["fileSIchunkshort"] = Util::formatBytes(getTotal());
	params["fileSIactual"] = Util::toString(getActual());
	params["fileSIactualshort"] = Util::formatBytes(getActual());
	params["speed"] = Util::formatBytes(getAverageSpeed()) + "/s";
	params["time"] = Util::formatSeconds((GET_TICK() - getStart()) / 1000);
	params["fileTR"] = getTTH().toBase32();
}
Ejemplo n.º 12
0
void ConnectionManager::adcConnect(const OnlineUser& aUser, uint16_t aPort, const string& aToken, bool secure) {
    if(shuttingDown)
        return;

    UserConnection* uc = getConnection(false, secure);
    uc->setToken(aToken);
    uc->setState(UserConnection::STATE_CONNECT);
    if(aUser.getIdentity().isOp()) {
        uc->setFlag(UserConnection::FLAG_OP);
    }
    try {
        uc->connect(aUser.getIdentity().getIp(), aPort);
    } catch(const Exception&) {
        putConnection(uc);
        delete uc;
    }
}
Ejemplo n.º 13
0
Download::Download(UserConnection& conn, QueueItem& qi, const string& path, bool supportsTrees) noexcept : Transfer(conn, path, qi.getTTH()),
    tempTarget(qi.getTempTarget()), file(0), treeValid(false)
{
    conn.setDownload(this);

    QueueItem::SourceConstIter source = qi.getSource(getUser());

    if(qi.isSet(QueueItem::FLAG_PARTIAL_LIST)) {
        setType(TYPE_PARTIAL_LIST);
    } else if(qi.isSet(QueueItem::FLAG_USER_LIST)) {
        setType(TYPE_FULL_LIST);
    }

    if(getType() == TYPE_FILE && qi.getSize() != -1) {
        if(HashManager::getInstance()->getTree(getTTH(), getTigerTree())) {
            setTreeValid(true);
            setSegment(qi.getNextSegment(getTigerTree().getBlockSize(), conn.getChunkSize(),conn.getSpeed(), source->getPartialSource()));
        } else if(supportsTrees && conn.isSet(UserConnection::FLAG_SUPPORTS_TTHL) && !qi.getSource(conn.getUser())->isSet(QueueItem::Source::FLAG_NO_TREE) && qi.getSize() > HashManager::MIN_BLOCK_SIZE) {
            // Get the tree unless the file is small (for small files, we'd probably only get the root anyway)
            setType(TYPE_TREE);
            getTigerTree().setFileSize(qi.getSize());
            setSegment(Segment(0, -1));
        } else {
            // Use the root as tree to get some sort of validation at least...
            getTigerTree() = TigerTree(qi.getSize(), qi.getSize(), getTTH());
            setTreeValid(true);
            setSegment(qi.getNextSegment(getTigerTree().getBlockSize(), 0, 0, source->getPartialSource()));
        }

        if(getSegment().getOverlapped()) {
            setFlag(FLAG_OVERLAP);

            // set overlapped flag to original segment
            for(DownloadList::const_iterator i = qi.getDownloads().begin(); i != qi.getDownloads().end(); ++i) {
                if((*i)->getSegment().contains(getSegment())) {
                    (*i)->setOverlapped(true);
                    break;
                }
            }
        }
    }
}
Ejemplo n.º 14
0
void Transfer::getParams(const UserConnection& aSource, StringMap& params) {
    params["userCID"] = aSource.getUser()->getCID().toBase32();
    params["userNI"] = Util::toString(ClientManager::getInstance()->getNicks(aSource.getUser()->getCID(), aSource.getHubUrl()));
    params["userI4"] = aSource.getRemoteIp();
    StringList hubNames = ClientManager::getInstance()->getHubNames(aSource.getUser()->getCID(), aSource.getHubUrl());
    if(hubNames.empty())
        hubNames.push_back(_("Offline"));
    params["hub"] = Util::toString(hubNames);
    StringList hubs = ClientManager::getInstance()->getHubs(aSource.getUser()->getCID(), aSource.getHubUrl());
    if(hubs.empty())
        hubs.push_back(_("Offline"));
    params["hubURL"] = Util::toString(hubs);
    params["fileSI"] = Util::toString(getSize());
    params["fileSIshort"] = Util::formatBytes(getSize());
    params["fileSIactual"] = Util::toString(getActual());
    params["fileSIactualshort"] = Util::formatBytes(getActual());
    params["speed"] = str(F_("%1%/s") % Util::formatBytes(getAverageSpeed()));
    params["time"] = Util::formatSeconds((GET_TICK() - getStart()) / 1000);
    params["fileTR"] = getTTH().toBase32();
}
Ejemplo n.º 15
0
void Transfer::getParams(const UserConnection& aSource, StringMap& params) const {
	params["userCID"] = aSource.getUser()->getCID().toBase32();
	params["userNI"] = Util::toString(ClientManager::getInstance()->getNicks(aSource.getUser()->getCID(), aSource.getHubUrl()));
	params["userI4"] = aSource.getRemoteIp();
	StringList hubNames = ClientManager::getInstance()->getHubNames(aSource.getUser()->getCID(), aSource.getHubUrl());
	if(hubNames.empty())
		hubNames.push_back(STRING(OFFLINE));
	params["hub"] = Util::toString(hubNames);
	StringList hubs = ClientManager::getInstance()->getHubs(aSource.getUser()->getCID(), aSource.getHubUrl());
	if(hubs.empty())
		hubs.push_back(STRING(OFFLINE));
	params["hubURL"] = Util::toString(hubs);
	params["fileSI"] = Util::toString(getSize());
	params["fileSIshort"] = Util::formatBytes(getSize());
	params["fileSIchunk"] = Util::toString(getPos());
	params["fileSIchunkshort"] = Util::formatBytes(getPos());
	params["fileSIactual"] = Util::toString(getActual());
	params["fileSIactualshort"] = Util::formatBytes(getActual());
	params["speed"] = Util::formatBytes(static_cast<int64_t>(getAverageSpeed())) + "/s";
	params["time"] = Text::fromT(Util::formatSeconds((GET_TICK() - getStart()) / 1000));
	params["fileTR"] = getTTH().toBase32();
}
Ejemplo n.º 16
0
void ConnectionManager::nmdcConnect(const string& aServer, uint16_t aPort, const string& aNick, const string& hubUrl) {
    if(shuttingDown)
        return;

    UserConnection* uc = getConnection(true, false);
    uc->setToken(aNick);
    uc->setHubUrl(hubUrl);
    uc->setState(UserConnection::STATE_CONNECT);
    uc->setFlag(UserConnection::FLAG_NMDC);
    try {
        uc->connect(aServer, aPort);
    } catch(const Exception&) {
        putConnection(uc);
        delete uc;
    }
}
Ejemplo n.º 17
0
Upload::Upload(UserConnection& conn, const string& path, const TTHValue& tth, unique_ptr<InputStream> aIS) : 
	Transfer(conn, path, tth), stream(move(aIS)) { 

	conn.setUpload(this);
}
Ejemplo n.º 18
0
bool UploadManager::prepareFile(UserConnection& aSource, const string& aType, const string& aFile, int64_t aStartPos, int64_t aBytes, bool listRecursive) {
	if(aFile.empty() || aStartPos < 0 || aBytes < -1 || aBytes == 0) {
		aSource.fileNotAvail("Invalid request");
		return false;
	}

	InputStream* is = 0;
	int64_t start = 0;
	int64_t bytesLeft = 0;
	int64_t size = 0;

	bool userlist = (aFile == Transfer::USER_LIST_NAME_BZ || aFile == Transfer::USER_LIST_NAME);
	bool free = userlist;
	bool leaves = false;
	bool partList = false;

	string sourceFile;
	try {
		if(aType == Transfer::TYPE_FILE) {
			sourceFile = ShareManager::getInstance()->toReal(aFile);

			if(aFile == Transfer::USER_LIST_NAME) {
				// Unpack before sending...
				string bz2 = File(sourceFile, File::READ, File::OPEN).read();
				string xml;
				CryptoManager::getInstance()->decodeBZ2(reinterpret_cast<const uint8_t*>(bz2.data()), bz2.size(), xml);
				// Clear to save some memory...
				string().swap(bz2);
				is = new MemoryInputStream(xml);
				start = 0;
				bytesLeft = size = xml.size();
			} else {
				File* f = new File(sourceFile, File::READ, File::OPEN);

				start = aStartPos;
				size = f->getSize();
				bytesLeft = (aBytes == -1) ? size : aBytes;

				if(size < (start + bytesLeft)) {
					aSource.fileNotAvail();
					delete f;
					return false;
				}

				free = free || (size <= (int64_t)(SETTING(FREE_SLOTS_SIZE) * 1024) );

				f->setPos(start);

				is = f;
				if((start + bytesLeft) < size) {
					is = new LimitedInputStream<true>(is, aBytes);
				}
			}
		} else if(aType == Transfer::TYPE_TTHL) {
			sourceFile = ShareManager::getInstance()->toReal(aFile);
			MemoryInputStream* mis = ShareManager::getInstance()->getTree(aFile);
			if(!mis) {
				aSource.fileNotAvail();
				return false;
			}

			start = 0;
			bytesLeft = size = mis->getSize();
			is = mis;
			leaves = true;
			free = true;
		} else {
			aSource.fileNotAvail("Unknown file type");
			return false;
		}
	} catch(const ShareException& e) {
		aSource.fileNotAvail(e.getError());
		return false;
	} catch(const Exception& e) {
		LogManager::getInstance()->message(STRING(UNABLE_TO_SEND_FILE) + sourceFile + ": " + e.getError());
		aSource.fileNotAvail();
		return false;
	}

	Lock l(cs);

	bool extraSlot = false;

	if(!aSource.isSet(UserConnection::FLAG_HASSLOT)) {
		bool hasReserved = (reservedSlots.find(aSource.getUser()) != reservedSlots.end());
		bool isFavorite = aSource.getUser()->getFavoriteGrantSlot();

		if(!(hasReserved || isFavorite || getFreeSlots() > 0 || getAutoSlot())) {
			bool supportsFree = aSource.isSet(UserConnection::FLAG_SUPPORTS_MINISLOTS);
			bool allowedFree = aSource.isSet(UserConnection::FLAG_HASEXTRASLOT) || aSource.isSet(UserConnection::FLAG_OP) || getFreeExtraSlots() > 0;
			if(free && supportsFree && allowedFree) {
				extraSlot = true;
			} else {
				delete is;
				aSource.maxedOut();

				// Check for tth root identifier
				string tFile = aFile;
				if (tFile.compare(0, 4, "TTH/") == 0)
					tFile = ShareManager::getInstance()->toVirtual(TTHValue(aFile.substr(4)));

				addFailedUpload(aSource, tFile +
					" (" + Util::toString((aStartPos*1000/(size+10))/10.0)+"% of " + Util::formatBytes(size) + " done)");
				aSource.disconnect();
				return false;
			}
		} else {
			clearUserFiles(aSource.getUser());	// this user is using a full slot, nix them.
		}

		setLastGrant(GET_TICK());
	}

	Upload* u = new Upload(aSource);
	u->setStream(is);
	if(aBytes == -1)
		u->setSize(size);
	else
		u->setSize(start + bytesLeft);

	u->setStartPos(start);
	u->setSourceFile(sourceFile);

	if(userlist)
		u->setFlag(Upload::FLAG_USER_LIST);
	if(leaves)
		u->setFlag(Upload::FLAG_TTH_LEAVES);
	if(partList)
		u->setFlag(Upload::FLAG_PARTIAL_LIST);

	uploads.push_back(u);

	if(!aSource.isSet(UserConnection::FLAG_HASSLOT)) {
		if(extraSlot) {
			if(!aSource.isSet(UserConnection::FLAG_HASEXTRASLOT)) {
				aSource.setFlag(UserConnection::FLAG_HASEXTRASLOT);
				extra++;
			}
		} else {
			if(aSource.isSet(UserConnection::FLAG_HASEXTRASLOT)) {
				aSource.unsetFlag(UserConnection::FLAG_HASEXTRASLOT);
				extra--;
			}
			aSource.setFlag(UserConnection::FLAG_HASSLOT);
			running++;
		}

		reservedSlots.erase(aSource.getUser());
	}

	return true;
}
Ejemplo n.º 19
0
Upload::Upload(UserConnection& conn) : Transfer(conn), stream(0) { 
	conn.setUpload(this);
}
Ejemplo n.º 20
0
Upload::Upload(UserConnection& conn, const string& path, const TTHValue& tth) : Transfer(conn, path, tth), stream(0) {
    conn.setUpload(this);
}
Ejemplo n.º 21
0
Download::Download(UserConnection& conn, QueueItem& qi) noexcept : Transfer(conn, qi.getTarget(), qi.getTTH()),
	tempTarget(qi.getTempTarget())
{
	conn.setDownload(this);
	
	QueueItem::SourceConstIter source = qi.getSource(getUser());

	if(qi.isSet(QueueItem::FLAG_PARTIAL_LIST)) {
		setType(TYPE_PARTIAL_LIST);
	} else if(qi.isSet(QueueItem::FLAG_USER_LIST)) {
		setType(TYPE_FULL_LIST);
	}

	if(source->isSet(QueueItem::Source::FLAG_PARTIAL))
		setFlag(FLAG_PARTIAL);
	if(qi.isSet(QueueItem::FLAG_CLIENT_VIEW))
		setFlag(FLAG_VIEW);
	if(qi.isSet(QueueItem::FLAG_MATCH_QUEUE))
		setFlag(FLAG_QUEUE);
	if(qi.isSet(QueueItem::FLAG_VIEW_NFO))
		setFlag(FLAG_NFO);
	if(qi.isSet(QueueItem::FLAG_RECURSIVE_LIST))
		setFlag(FLAG_RECURSIVE);
	if(qi.isSet(QueueItem::FLAG_TTHLIST_BUNDLE))
		setFlag(FLAG_TTHLIST_BUNDLE);
	if (qi.getPriority() == QueueItemBase::HIGHEST)
		setFlag(FLAG_HIGHEST_PRIO);

	if (qi.getBundle()) {
		dcassert(!qi.isSet(QueueItem::FLAG_USER_LIST));
		dcassert(!qi.isSet(QueueItem::FLAG_TEXT));
		setBundle(qi.getBundle());
	}
	
	if(getType() == TYPE_FILE && qi.getSize() != -1) {
		if(HashManager::getInstance()->getTree(getTTH(), getTigerTree())) {
			setTreeValid(true);
			setSegment(qi.getNextSegment(getTigerTree().getBlockSize(), conn.getChunkSize(), conn.getSpeed(), source->getPartialSource(), true));
			qi.setBlockSize(getTigerTree().getBlockSize());
		} else if(conn.isSet(UserConnection::FLAG_SUPPORTS_TTHL) && !source->isSet(QueueItem::Source::FLAG_NO_TREE) && qi.getSize() > HashManager::MIN_BLOCK_SIZE) {
			// Get the tree unless the file is small (for small files, we'd probably only get the root anyway)
			setType(TYPE_TREE);
			getTigerTree().setFileSize(qi.getSize());
			setSegment(Segment(0, -1));
		} else {
			// Use the root as tree to get some sort of validation at least...
			getTigerTree() = TigerTree(qi.getSize(), qi.getSize(), getTTH());
			setTreeValid(true);
			setSegment(qi.getNextSegment(getTigerTree().getBlockSize(), 0, 0, source->getPartialSource(), true));
		}
		
		if ((getStartPos() + getSegmentSize()) != qi.getSize() || (conn.getDownload() && conn.getDownload()->isSet(FLAG_CHUNKED))) {
			setFlag(FLAG_CHUNKED);
		}

		if(getSegment().getOverlapped()) {
			setFlag(FLAG_OVERLAP);

			// set overlapped flag to original segment
			for(auto d: qi.getDownloads()) {
				if(d->getSegment().contains(getSegment())) {
					d->setOverlapped(true);
					break;
				}
			}
		}
	}
}
Ejemplo n.º 22
0
Upload::Upload(UserConnection& conn, const string& path, const TTHValue& tth) : Transfer(conn, path, tth), stream(0), fileSize(-1), delayTime(0) { 
	conn.setUpload(this);
}