- initial import

This commit is contained in:
2018-06-05 11:05:37 +03:00
commit e1a4931375
4673 changed files with 1383093 additions and 0 deletions

View File

@@ -0,0 +1,493 @@
/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ICEPlatform.h"
#include "ICEStunTransaction.h"
#include "ICEStunAttributes.h"
#include "ICELog.h"
#include "ICEError.h"
#include "ICEAction.h"
#include "ICETime.h"
#ifndef _WIN32
# include <stdexcept>
#endif
using namespace ice;
#define LOG_SUBSYSTEM "ICE"
const char* Transaction::stateToString(State state)
{
switch (state)
{
case Running: return "Running";
case Failed: return "Failed";
case Success: return "Success";
}
return "Undefined";
}
Transaction::Transaction()
{
mTransportType = IPv4;
// There is no default ICE stack
mStackID = 0;
// There is no default logger
mLog = NULL;
// Packet is not composed in constructor
mComposed = false;
// Initial state of transaction - "Running"
mState = Transaction::Running;
// Reset user data
mTag = 0;
// Do not use message integrity attribute by default
mMessageIntegrity = false;
// Do not use fingerprint attribute by default
mFingerprint = false;
// Do not use long term credentials by default
mLongTerm = false;
// Do not use short term credentials by default
mShortTerm = false;
// Create new transaction ID
generateId();
// CONTROLLING attribute is not used by default
mEnableControlling = false;
// CONTROLLED attribute is not used by default
mEnableControlled = false;
// PRIORITY attribute is not used by default
mEnablePriority = false;
mPriority = 0;
// Transaction is not cancelled
mCancelled = false;
// Transaction is not relayed by default
mRelayed = false;
// Component port is not set by default
mComponent = 0;
mKeepalive = false;
mInterval = 0;
mUserObject = NULL;
mType = None;
mRemoved = false;
mFailoverId = 0;
}
Transaction::~Transaction()
{
}
void Transaction::generateId()
{
for (size_t i=0; i<12; i++)
mTransactionID.mValue[i] = rand();
}
void Transaction::setStackId(int id)
{
mStackID = id;
}
int Transaction::stackId()
{
return mStackID;
}
void Transaction::setTransportType(int _type)
{
assert(_type == IPv4 || _type == IPv6);
mTransportType = _type;
}
int Transaction::transportType()
{
return mTransportType;
}
std::string Transaction::toStdString()
{
std::ostringstream output;
output << "State: " << Transaction::stateToString(mState) << ", ";
output << "Transport: " << (mTransportType == IPv4 ? "IPv4" : "IPv6") << ", ";
output << (mCancelled ? "Cancelled, " : "");
output << "Destination: " << mDestination.toStdString().c_str() << ", ";
output << "Comment: " << mComment.c_str();
return output.str();
}
void Transaction::setTag(unsigned int tag)
{
mTag = tag;
}
unsigned Transaction::tag()
{
return mTag;
}
void Transaction::enqueueMessage(ice::StunMessage& msg)
{
// Clear outgoing buffer
mOutgoingData.clear();
// Check if message should be secured by message integrity
std::string password = mPassword;
if (true == mMessageIntegrity)
{
// Ensure credentials are enabled
assert(mLongTerm || mShortTerm);
// Create username attribute
Username* attr = new Username();
// Set username value
if (mLongTerm || mShortTerm)
attr->setValue(mUsername);
// Add username attribute itself
msg.setAttribute(attr);
// Add message integrity attribute
msg.setAttribute(new MessageIntegrity());
}
if (mFingerprint)
msg.setAttribute(new Fingerprint());
// Add ICE-CONTROLLED attribute if needed
if (mEnableControlled)
{
assert(mTieBreaker.length() == 8);
ControlledAttr* attr = new ControlledAttr();
attr->setTieBreaker(mTieBreaker);
msg.setAttribute(attr);
}
// Add ICE-CONTROLLING attribute if needed
if (mEnableControlling)
{
assert(mTieBreaker.length() == 8);
ControllingAttr* attr = new ControllingAttr();
attr->setTieBreaker(mTieBreaker);
msg.setAttribute(attr);
}
// Add ICE-PRIORITY attribute if needed
if (mEnablePriority)
{
ICEPriority* attr = new ICEPriority();
attr->setPriority(mPriority);
msg.setAttribute(attr);
}
msg.buildPacket(mOutgoingData, password);
}
ByteBuffer* Transaction::generateData(bool force)
{
if (mCancelled)
return NULL;
// Check if there is any outgoing data
if (mOutgoingData.size() == 0)
return NULL;
// Check if there is timeout for next transmission attempt
if (mRTOTimer.isTimeout() && !force)
{
ICELogCritical(<< "Transaction " << mComment << " timeouted.");
return NULL;
}
// Check if transmission was made too much times - client should not send billions of packets.
if (mRTOTimer.isAttemptLimitReached() && !force)
return NULL;
// Check if time to retransmit now
if (mRTOTimer.isTimeToRetransmit() || force)
{
mRTOTimer.attemptMade();
// Copy outgoing data
ByteBuffer* buffer = new ByteBuffer(mOutgoingData);
buffer->setComment(mComment);
buffer->setRemoteAddress(destination());
buffer->setComponent(component());
buffer->setComment(comment());
buffer->setTag(this);
return buffer;
}
else
{
}
return NULL;
}
void Transaction::restart()
{
mComposed = false;
mState = Transaction::Running;
mOutgoingData.clear();
mRemoved = false;
mRTOTimer.stop();
mRTOTimer.start();
}
bool Transaction::isTimeout()
{
if (mRTOTimer.isTimeout())
{
mState = Failed;
return true;
}
else
return false;
}
void Transaction::addMessageIntegrity(bool enable)
{
mMessageIntegrity = enable;
}
void Transaction::addFingerprint(bool enable)
{
mFingerprint = enable;
}
void Transaction::addShortTermCredentials(bool enable)
{
this->mShortTerm = enable;
}
void Transaction::addLongTermCredentials(bool enable)
{
this->mLongTerm = enable;
}
void Transaction::addControllingRole(const std::string& tieBreaker)
{
mEnableControlling = true;
mTieBreaker = tieBreaker;
}
void Transaction::addControlledRole(const std::string& tieBreaker)
{
mEnableControlled = true;
mTieBreaker = tieBreaker;
}
void Transaction::addPriority(unsigned int priority)
{
mEnablePriority = true;
mPriority = priority;
}
unsigned int Transaction::priorityValue()
{
if (!mEnablePriority)
throw Exception(NO_PRIORITY_ATTRIBUTE);
return mPriority;
}
void Transaction::setUsername(const std::string& username)
{
mUsername = username;
}
void Transaction::setPassword(const std::string& password)
{
mPassword = password;
}
Transaction::State Transaction::state() const
{
return mState;
}
void Transaction::setAction(PAction action)
{
mAction = action;
}
PAction Transaction::action() const
{
return mAction;
}
void Transaction::cancel()
{
mCancelled = true;
}
bool Transaction::isCancelled() const
{
return mCancelled;
}
void Transaction::setComment(const std::string& comment)
{
mComment = comment;
}
std::string Transaction::comment() const
{
return mComment;
}
void Transaction::setDestination(const NetworkAddress& addr)
{
mDestination = addr;
}
void Transaction::setComponent(int component)
{
mComponent = component;
}
int Transaction::component()
{
return mComponent;
}
NetworkAddress& Transaction::destination()
{
return mDestination;
}
bool Transaction::relayed()
{
return mRelayed;
}
void Transaction::setRelayed(bool relayed)
{
mRelayed = relayed;
}
bool Transaction::keepalive()
{
return mKeepalive;
}
void Transaction::setKeepalive(bool keepalive)
{
mKeepalive = keepalive;
}
unsigned Transaction::interval()
{
return mInterval;
}
void Transaction::setInterval(unsigned interval)
{
mInterval = interval;
}
void* Transaction::userObject()
{
return mUserObject;
}
void Transaction::setUserObject(void* obj)
{
mUserObject = obj;
}
Transaction::Type Transaction::type()
{
return mType;
}
void Transaction::setType(Transaction::Type t)
{
mType = t;
}
bool Transaction::removed()
{
return mRemoved;
}
void Transaction::setRemoved(bool removed)
{
if (!mRemoved && removed)
ICELogDebug(<< "Transaction " << mComment << " removed.");
mRemoved = removed;
}
unsigned Transaction::timestamp()
{
return mTimestamp;
}
void Transaction::setTimestamp(unsigned timestamp)
{
mTimestamp = timestamp;
}
StunMessage::TransactionID Transaction::transactionId()
{
return mTransactionID;
}
bool Transaction::hasToRunNow()
{
if (!mKeepalive)
return true;
//bool cf = (mComment == "ClientRefresh");
unsigned current = ICETimeHelper::timestamp();
/*if (cf)
{
ICELogDebug(<< "ClientRefresh interval: " << ICETimeHelper::findDelta(timestamp(), current) << ", interval " << interval()*1000);
}*/
if (timestamp())
{
if (ICETimeHelper::findDelta(timestamp(), current) < interval() * 1000)
return false;
setTimestamp(current);
return true;
}
else
{
setTimestamp(current);
return false;
}
}
void Transaction::setFailoverId(int failoverId)
{
mFailoverId = failoverId;
}
int Transaction::failoverId() const
{
return mFailoverId;
}