/*
* Copyright (C) 2008-2014 The QXmpp developers
*
* Author:
* Jeremy Lainé
*
* Source:
* https://github.com/qxmpp-project/qxmpp
*
* This file is a part of QXmpp library.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
*/
#define QXMPP_DEBUG_STUN
#include <QCryptographicHash>
#include <QDataStream>
#include <QHostInfo>
#include <QNetworkInterface>
#include <QUdpSocket>
#include <QTimer>
#include "QXmppStun_p.h"
#include "QXmppUtils.h"
#define STUN_ID_SIZE 12
#define STUN_RTO_INTERVAL 500
#define STUN_RTO_MAX 7
static const quint32 STUN_MAGIC = 0x2112A442;
static const quint16 STUN_HEADER = 20;
static const quint8 STUN_IPV4 = 0x01;
static const quint8 STUN_IPV6 = 0x02;
static const char* gathering_states[] = {
"new",
"gathering",
"complete"
};
static const char* pair_states[] = {
"frozen",
"waiting",
"in-progress",
"succeeded",
"failed"
};
enum AttributeType {
MappedAddress = 0x0001, // RFC5389
ChangeRequest = 0x0003, // RFC5389
SourceAddress = 0x0004, // RFC5389
ChangedAddress = 0x0005, // RFC5389
Username = 0x0006, // RFC5389
MessageIntegrity = 0x0008, // RFC5389
ErrorCode = 0x0009, // RFC5389
ChannelNumber = 0x000c, // RFC5766 : TURN
Lifetime = 0x000d, // RFC5766 : TURN
XorPeerAddress = 0x0012, // RFC5766 : TURN
DataAttr = 0x0013, // RFC5766 : TURN
Realm = 0x0014, // RFC5389
Nonce = 0x0015, // RFC5389
XorRelayedAddress= 0x0016, // RFC5766 : TURN
EvenPort = 0x0018, // RFC5766 : TURN
RequestedTransport=0x0019, // RFC5766 : TURN
XorMappedAddress = 0x0020, // RFC5389
ReservationToken = 0x0022, // RFC5766 : TURN
Priority = 0x0024, // RFC5245
UseCandidate = 0x0025, // RFC5245
Software = 0x8022, // RFC5389
Fingerprint = 0x8028, // RFC5389
IceControlled = 0x8029, // RFC5245
IceControlling = 0x802a, // RFC5245
OtherAddress = 0x802c // RFC5780
};
// FIXME : we need to set local preference to discriminate between
// multiple IP addresses
static quint32 candidatePriority(const QXmppJingleCandidate &candidate, int localPref = 65535)
{
int typePref;
switch (candidate.type())
{
case QXmppJingleCandidate::HostType:
typePref = 126;
break;
case QXmppJingleCandidate::PeerReflexiveType:
typePref = 110;
break;
case QXmppJingleCandidate::ServerReflexiveType:
typePref = 100;
break;
default:
typePref = 0;
}
return (1 << 24) * typePref + \
(1 << 8) * localPref + \
(256 - candidate.component());
}
static QString computeFoundation(QXmppJingleCandidate::Type type, const QString &protocol, const QHostAddress &baseAddress)
{
QCryptographicHash hash(QCryptographicHash::Md5);
hash.addData((QString::number(type) + protocol + baseAddress.toString()).toUtf8());
return hash.result().toHex();
}
static bool isIPv6LinkLocalAddress(const QHostAddress &addr)
{
if (addr.protocol() != QAbstractSocket::IPv6Protocol)
return false;
Q_IPV6ADDR ipv6addr = addr.toIPv6Address();
return (((ipv6addr[0] << 8) + ipv6addr[1]) & 0xffc0) == 0xfe80;
}
static bool isLoopbackAddress(const QHostAddress &addr)
{
return (addr.toIPv4Address() & 0xff000000) == 0x7f000000;
}
// Returns true if the two addresses are compatible.
static bool isCompatibleAddress(const QHostAddress &a1, const QHostAddress &a2)
{
return a1.protocol() == a2.protocol() &&
isIPv6LinkLocalAddress(a1) == isIPv6LinkLocalAddress(a2);
}
static bool decodeAddress(QDataStream &stream, quint16 a_length, QHostAddress &address, quint16 &port, const QByteArray &xorId = QByteArray())
{
if (a_length < 4)
return false;
quint8 reserved, protocol;
quint16 rawPort;
stream >> reserved;
stream >> protocol;
stream >> rawPort;
if (xorId.isEmpty())
port = rawPort;
else
port = rawPort ^ (STUN_MAGIC >> 16);
if (protocol == STUN_IPV4)
{
if (a_length != 8)
return false;
quint32 addr;
stream >> addr;
if (xorId.isEmpty())
address = QHostAddress(addr);
else
address = QHostAddress(addr ^ STUN_MAGIC);
} else if (protocol == STUN_IPV6) {
if (a_length != 20)
return false;
Q_IPV6ADDR addr;
stream.readRawData((char*)&addr, sizeof(addr));
if (!xorId.isEmpty())
{
QByteArray xpad;
QDataStream(&xpad, QIODevice::WriteOnly) << STUN_MAGIC;
xpad += xorId;
for (int i = 0; i < 16; i++)
addr[i] ^= xpad[i];
}
address = QHostAddress(addr);
} else {
return false;
}
return true;
}
static void encodeAddress(QDataStream &stream, quint16 type, const QHostAddress &address, quint16 port, const QByteArray &xorId = QByteArray())
{
const quint8 reserved = 0;
if (address.protocol() == QAbstractSocket::IPv4Protocol)
{
stream << type;
stream << quint16(8);
stream << reserved;
stream << quint8(STUN_IPV4);
quint32 addr = address.toIPv4Address();
if (!xorId.isEmpty())
{
port ^= (STUN_MAGIC >> 16);
addr ^= STUN_MAGIC;
}
stream << port;
stream << addr;
} else if (address.protocol() == QAbstractSocket::IPv6Protocol) {
stream << type;
stream << quint16(20);
stream << reserved;
stream << quint8(STUN_IPV6);
Q_IPV6ADDR addr = address.toIPv6Address();
if (!xorId.isEmpty())
{
port ^= (STUN_MAGIC >> 16);
QByteArray xpad;
QDataStream(&xpad, QIODevice::WriteOnly) << STUN_MAGIC;
xpad += xorId;
for (int i = 0; i < 16; i++)
addr[i] ^= xpad[i];
}
stream << port;
stream.writeRawData((char*)&addr, sizeof(addr));
} else {
qWarning("Cannot write STUN attribute for unknown IP version");
}
}
static void addAddress(QDataStream &stream, quint16 type, const QHostAddress &host, quint16 port, const QByteArray &xorId = QByteArray())
{
if (port && !host.isNull() &&
(host.protocol() == QAbstractSocket::IPv4Protocol ||
host.protocol() == QAbstractSocket::IPv6Protocol))
{
encodeAddress(stream, type, host, port, xorId);
}
}
static void encodeString(QDataStream &stream, quint16 type, const QString &string)
{
const QByteArray utf8string = string.toUtf8();
stream << type;
stream << quint16(utf8string.size());
stream.writeRawData(utf8string.data(), utf8string.size());
if (utf8string.size() % 4)
{
const QByteArray padding(4 - (utf8string.size() % 4), 0);
stream.writeRawData(padding.data(), padding.size());
}
}
static void setBodyLength(QByteArray &buffer, qint16 length)
{
QDataStream stream(&buffer, QIODevice::WriteOnly);
stream.device()->seek(2);
stream << length;
}
/// Constructs a new QXmppStunMessage.
QXmppStunMessage::QXmppStunMessage()
: errorCode(0),
changedPort(0),
mappedPort(0),
otherPort(0),
sourcePort(0),
xorMappedPort(0),
xorPeerPort(0),
xorRelayedPort(0),
useCandidate(false),
m_cookie(STUN_MAGIC),
m_type(0),
m_changeRequest(0),
m_channelNumber(0),
m_lifetime(0),
m_priority(0)
{
m_id = QBy
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
,程序整体架构采用插件框架,各摸块通过插件管理器与主系统进行通讯,主系统主要功能包含xmpp、Mqtt即时通讯,opencv视觉处理,vtk3D点云显示,WebEngine展示WebGL或三维页面,线性动画等 管理系统是一种通过计算机技术实现的用于组织、监控和控制各种活动的软件系统。这些系统通常被设计用来提高效率、减少错误、加强安全性,同时提供数据和信息支持。以下是一些常见类型的管理系统: 学校管理系统: 用于学校或教育机构的学生信息、教职员工信息、课程管理、成绩记录、考勤管理等。学校管理系统帮助提高学校的组织效率和信息管理水平。 人力资源管理系统(HRM): 用于处理组织内的人事信息,包括员工招聘、培训记录、薪资管理、绩效评估等。HRM系统有助于企业更有效地管理人力资源,提高员工的工作效率和满意度。 库存管理系统: 用于追踪和管理商品或原材料的库存。这种系统可以帮助企业避免库存过剩或不足的问题,提高供应链的效率。 客户关系管理系统(CRM): 用于管理与客户之间的关系,包括客户信息、沟通记录、销售机会跟踪等。CRM系统有助于企业更好地理解客户需求,提高客户满意度和保留率。 医院管理系统: 用于管理医院或医疗机构的患者信息、医生排班、药品库存等。这种系统可以提高医疗服务的质量和效率。 财务管理系统: 用于记录和管理组织的财务信息,包括会计凭证、财务报表、预算管理等。财务管理系统
资源推荐
资源详情
资源评论
























收起资源包目录





































































































共 540 条
- 1
- 2
- 3
- 4
- 5
- 6
资源评论


JJJ69
- 粉丝: 6462
上传资源 快速赚钱
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


最新资源
- 迭代式教学法在高职计算机类项目化课程中的实践研究.docx
- 基于网络通讯中信息安全的保障研究分析.docx
- kunlun-atp-Python资源
- modelcontextprotocol_swift-sdk-Swift资源
- 单片机水位控制系统设计方案.doc
- 大数据背景下教育统计数据有效利用的问题与对策.docx
- 网络环境下信息技术课引导学生有效利用网络的实践研究.docx
- 运用海洋调查和物联网技术建立渤海突发环境事件预警体系初探-畜牧渔业论文.doc
- matlab学习-Matlab资源
- 认识深度学习中的知识蒸馏.docx
- 基于大数据时代高职院校手机APP信息化教学模式探索.docx
- JAVA网上书店大学本科方案设计书.doc
- 探讨无人机系统研制项目管理体系和方法.docx
- WeUI-Kotlin资源
- 大数据技术在事业单位档案管理中的应用研究.docx
- 软件工程试题与答案28.doc
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈



安全验证
文档复制为VIP权益,开通VIP直接复制
