merged upstream/master

This commit is contained in:
csoler 2020-02-17 19:54:16 +01:00
commit 167380127b
No known key found for this signature in database
GPG key ID: 7BCA522266C0804C
80 changed files with 1225 additions and 782 deletions

View file

@ -12,10 +12,6 @@ DESTDIR = lib
!include("use_libretroshare.pri"):error("Including")
# the dht stunner is used to obtain RS external ip addr. when it is natted
# this system is unreliable and rs supports a newer and better one (asking connected peers)
# CONFIG += useDhtStunner
# treat warnings as error for better removing
#QMAKE_CFLAGS += -Werror
#QMAKE_CXXFLAGS += -Werror

View file

@ -711,47 +711,6 @@ void p3NetMgrIMPL::netExtCheck()
}
}
#ifdef ALLOW_DHT_STUNNER
// (cyril) I disabled this because it's pretty dangerous. The DHT can report a wrong address quite easily
// if the other DHT peers are not collaborating.
/* Next ask the DhtStunner */
{
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
std::cerr << "p3NetMgrIMPL::netExtCheck() Ext Not Ok, Checking DhtStunner" << std::endl;
#endif
uint8_t isstable = 0;
struct sockaddr_storage tmpaddr;
sockaddr_storage_clear(tmpaddr);
if (mDhtStunner)
{
/* input network bits */
if (mDhtStunner->getExternalAddr(tmpaddr, isstable))
{
if((rsBanList == NULL) || rsBanList->isAddressAccepted(tmpaddr,RSBANLIST_CHECKING_FLAGS_BLACKLIST))
{
// must be stable???
isStable = (isstable == 1);
//mNetFlags.mExtAddr = tmpaddr;
mNetFlags.mExtAddrOk = true;
mNetFlags.mExtAddrStableOk = isStable;
address_votes[tmpaddr].n++ ;
#ifdef NETMGR_DEBUG_STATEBOX
std::cerr << "p3NetMgrIMPL::netExtCheck() From DhtStunner: ";
std::cerr << sockaddr_storage_tostring(tmpaddr);
std::cerr << " Stable: " << (uint32_t) isstable;
std::cerr << std::endl;
#endif
}
else
std::cerr << "(SS) DHTStunner returned wrong own IP " << sockaddr_storage_iptostring(tmpaddr) << " (banned). Rejecting." << std::endl;
}
}
}
#endif
/* ask ExtAddrFinder */
{
/* ExtAddrFinder */
@ -829,6 +788,49 @@ void p3NetMgrIMPL::netExtCheck()
#endif
}
#ifdef ALLOW_DHT_STUNNER
// (cyril) I disabled this because it's pretty dangerous. The DHT can report a wrong address quite easily
// if the other DHT peers are not collaborating.
// (sehraf) For the record: The udp stunner uses multiple (as for now: two) peers to ensure that the IP recieved is the correct one, see UdpStunner::locked_checkExternalAddress()
// Nevertheless this stays a more risky method to determine the external ip address.
/* lastly ask the DhtStunner as fallback */
if (address_votes.empty()) {
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
std::cerr << "p3NetMgrIMPL::netExtCheck() Ext Not Ok, Checking DhtStunner" << std::endl;
#endif
uint8_t isstable = 0;
struct sockaddr_storage tmpaddr;
sockaddr_storage_clear(tmpaddr);
if (mDhtStunner)
{
/* input network bits */
if (mDhtStunner->getExternalAddr(tmpaddr, isstable))
{
if((rsBanList == NULL) || rsBanList->isAddressAccepted(tmpaddr,RSBANLIST_CHECKING_FLAGS_BLACKLIST))
{
// must be stable???
isStable = (isstable == 1);
//mNetFlags.mExtAddr = tmpaddr;
mNetFlags.mExtAddrOk = true;
mNetFlags.mExtAddrStableOk = isStable;
address_votes[tmpaddr].n++ ;
#ifdef NETMGR_DEBUG_STATEBOX
std::cerr << "p3NetMgrIMPL::netExtCheck() From DhtStunner: ";
std::cerr << sockaddr_storage_tostring(tmpaddr);
std::cerr << " Stable: " << (uint32_t) isstable;
std::cerr << std::endl;
#endif
}
else
std::cerr << "(SS) DHTStunner returned wrong own IP " << sockaddr_storage_iptostring(tmpaddr) << " (banned). Rejecting." << std::endl;
}
}
}
#endif
/* any other sources ??? */
/* finalise address */

View file

@ -512,10 +512,10 @@ public:
RS_DEPRECATED_FOR(getChannelsInfo)
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsChannelGroup> &groups) = 0;
RS_DEPRECATED_FOR(getChannelsContent)
RS_DEPRECATED_FOR(getChannelContent)
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts, std::vector<RsGxsComment> &cmts) = 0;
RS_DEPRECATED_FOR(getChannelsContent)
RS_DEPRECATED_FOR(getChannelContent)
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts) = 0;
/**

View file

@ -3,7 +3,7 @@
* *
* libretroshare: retroshare core library *
* *
* Copyright 2008-2012 by Robert Fernie <retroshare@lunamutt.com> *
* Copyright 2008-2020 by Robert Fernie <retroshare@lunamutt.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -26,6 +26,7 @@
#include <string>
#include <list>
#include "rsgxsservice.h"
#include "rsgxscommon.h"
/* The Main Interface Class - for information about your Peers */
class RsPhoto;
@ -37,21 +38,6 @@ extern RsPhoto *rsPhoto;
#define RSPHOTO_MODE_OWN 2
#define RSPHOTO_MODE_REMOTE 3
class RsPhotoThumbnail
{
public:
RsPhotoThumbnail()
:data(NULL), size(0), type("N/A") { return; }
bool deleteImage();
bool copyFrom(const RsPhotoThumbnail &nail);
// Holds Thumbnail image.
uint8_t *data;
uint32_t size;
std::string type;
};
/* If these flags are no set - the Photo inherits values from the Album
*/
@ -96,7 +82,7 @@ class RsPhotoPhoto
int mOrder;
RsPhotoThumbnail mThumbnail;
RsGxsImage mThumbnail;
int mMode;
@ -137,7 +123,7 @@ class RsPhotoAlbum
std::string mHashTags;
RsPhotoThumbnail mThumbnail;
RsGxsImage mThumbnail;
int mMode;

View file

@ -3,7 +3,8 @@
* *
* libretroshare: retroshare core library *
* *
* Copyright 2008-2012 by Robert Fernie, Christopher Evi-Parker *
* Copyright (C) 2008-2012 Robert Fernie, Christopher Evi-Parker *
* Copyright (C) 2020 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -19,8 +20,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#ifndef RETROSHARE_GXS_RSPOSTED_GUI_INTERFACE_H
#define RETROSHARE_GXS_RSPOSTED_GUI_INTERFACE_H
#pragma once
#include <inttypes.h>
#include <string>
@ -32,20 +32,62 @@
#include "retroshare/rsgxscommon.h"
#include "serialiser/rsserializable.h"
/* The Main Interface Class - for information about your Posted */
class RsPosted;
extern RsPosted *rsPosted;
class RsPostedPost;
class RsPostedGroup
/**
* Pointer to global instance of RsGxsChannels service implementation
* @jsonapi{development}
*/
extern RsPosted* rsPosted;
struct RsPostedGroup
{
public:
RsPostedGroup() { return; }
RsGroupMetaData mMeta;
std::string mDescription;
RsGxsImage mGroupImage;
};
struct RsPostedPost
{
RsPostedPost(): mHaveVoted(false), mUpVotes(0), mDownVotes(0), mComments(0),
mHotScore(0), mTopScore(0), mNewScore(0) {}
bool calculateScores(rstime_t ref_time);
RsMsgMetaData mMeta;
std::string mLink;
std::string mNotes;
bool mHaveVoted;
// Calculated.
uint32_t mUpVotes;
uint32_t mDownVotes;
uint32_t mComments;
// and Calculated Scores:???
double mHotScore;
double mTopScore;
double mNewScore;
RsGxsImage mImage;
/// @see RsSerializable
/*virtual void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx )
{
RS_SERIAL_PROCESS(mImage);
RS_SERIAL_PROCESS(mMeta);
RS_SERIAL_PROCESS(mLink);
RS_SERIAL_PROCESS(mHaveVoted);
RS_SERIAL_PROCESS(mUpVotes);
RS_SERIAL_PROCESS(mDownVotes);
RS_SERIAL_PROCESS(mComments);
RS_SERIAL_PROCESS(mHotScore);
RS_SERIAL_PROCESS(mTopScore);
RS_SERIAL_PROCESS(mNewScore);
}*/
};
@ -65,9 +107,6 @@ class RsPostedGroup
#define RSPOSTED_VIEWMODE_COMMENTS 4
std::ostream &operator<<(std::ostream &out, const RsPostedGroup &group);
std::ostream &operator<<(std::ostream &out, const RsPostedPost &post);
enum class RsPostedEventCode: uint8_t
{
UNKNOWN = 0x00,
@ -98,25 +137,41 @@ struct RsGxsPostedEvent: RsEvent
RS_SERIAL_PROCESS(mPostedGroupId);
RS_SERIAL_PROCESS(mPostedMsgId);
}
~RsGxsPostedEvent() override;
};
class RsPosted : public RsGxsIfaceHelper, public RsGxsCommentService
{
public:
enum RankType {TopRankType, HotRankType, NewRankType };
//static const uint32_t FLAG_MSGTYPE_POST;
//static const uint32_t FLAG_MSGTYPE_MASK;
public:
explicit RsPosted(RsGxsIface& gxs) : RsGxsIfaceHelper(gxs) {}
virtual ~RsPosted() {}
/* Specific Service Data */
virtual bool getGroupData(const uint32_t &token, std::vector<RsPostedGroup> &groups) = 0;
virtual bool getPostData(const uint32_t &token, std::vector<RsPostedPost> &posts, std::vector<RsGxsComment> &cmts) = 0;
virtual bool getPostData(const uint32_t &token, std::vector<RsPostedPost> &posts) = 0;
//Not currently used
virtual bool getBoardsInfo(
const std::list<RsGxsGroupId>& boardsIds,
std::vector<RsPostedGroup>& boardsInfo ) = 0;
virtual bool getBoardContent(
const RsGxsGroupId& boardId,
const std::set<RsGxsMessageId>& contentsIds,
std::vector<RsPostedPost>& posts,
std::vector<RsGxsComment>& comments ) = 0;
enum RS_DEPRECATED RankType {TopRankType, HotRankType, NewRankType };
RS_DEPRECATED_FOR(getBoardsInfo)
virtual bool getGroupData( const uint32_t& token,
std::vector<RsPostedGroup> &groups ) = 0;
RS_DEPRECATED_FOR(getBoardsContent)
virtual bool getPostData(
const uint32_t& token, std::vector<RsPostedPost>& posts,
std::vector<RsGxsComment>& cmts) = 0;
RS_DEPRECATED_FOR(getBoardsContent)
virtual bool getPostData(
const uint32_t& token, std::vector<RsPostedPost>& posts) = 0;
//Not currently used
//virtual bool getRelatedPosts(const uint32_t &token, std::vector<RsPostedPost> &posts) = 0;
/* From RsGxsCommentService */
@ -134,62 +189,6 @@ virtual bool createPost(uint32_t &token, RsPostedPost &post) = 0;
virtual bool updateGroup(uint32_t &token, RsPostedGroup &group) = 0;
virtual bool groupShareKeys(const RsGxsGroupId& group,const std::set<RsPeerId>& peers) = 0 ;
virtual ~RsPosted();
};
class RsPostedPost
{
public:
RsPostedPost()
{
//mMeta.mMsgFlags = RsPosted::FLAG_MSGTYPE_POST;
mUpVotes = 0;
mDownVotes = 0;
mComments = 0;
mHaveVoted = false;
mHotScore = 0;
mTopScore = 0;
mNewScore = 0;
}
bool calculateScores(rstime_t ref_time);
RsMsgMetaData mMeta;
std::string mLink;
std::string mNotes;
bool mHaveVoted;
// Calculated.
uint32_t mUpVotes;
uint32_t mDownVotes;
uint32_t mComments;
// and Calculated Scores:???
double mHotScore;
double mTopScore;
double mNewScore;
RsGxsImage mImage;
/// @see RsSerializable
/*virtual void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx )
{
RS_SERIAL_PROCESS(mImage);
RS_SERIAL_PROCESS(mMeta);
RS_SERIAL_PROCESS(mLink);
RS_SERIAL_PROCESS(mHaveVoted);
RS_SERIAL_PROCESS(mUpVotes);
RS_SERIAL_PROCESS(mDownVotes);
RS_SERIAL_PROCESS(mComments);
RS_SERIAL_PROCESS(mHotScore);
RS_SERIAL_PROCESS(mTopScore);
RS_SERIAL_PROCESS(mNewScore);
}*/
};
#endif // RETROSHARE_GXS_RSPOSTED_GUI_INTERFACE_H

View file

@ -26,39 +26,34 @@
#include "serialiser/rstlvbinary.h"
#include "serialiser/rstypeserializer.h"
#define GXS_PHOTO_SERIAL_DEBUG
RsItem *RsGxsPhotoSerialiser::create_item(uint16_t service, uint8_t item_sub_id) const
{
if(service != RS_SERVICE_GXS_TYPE_PHOTO)
return NULL ;
if(service != RS_SERVICE_GXS_TYPE_PHOTO)
return NULL ;
switch(item_sub_id)
{
case RS_PKT_SUBTYPE_PHOTO_COMMENT_ITEM: return new RsGxsPhotoCommentItem() ;
case RS_PKT_SUBTYPE_PHOTO_SHOW_ITEM: return new RsGxsPhotoAlbumItem() ;
case RS_PKT_SUBTYPE_PHOTO_ITEM: return new RsGxsPhotoPhotoItem() ;
default:
return NULL ;
}
switch(item_sub_id)
{
case RS_PKT_SUBTYPE_PHOTO_COMMENT_ITEM: return new RsGxsPhotoCommentItem() ;
case RS_PKT_SUBTYPE_PHOTO_SHOW_ITEM: return new RsGxsPhotoPhotoItem() ;
case RS_PKT_SUBTYPE_PHOTO_ITEM: return new RsGxsPhotoAlbumItem() ;
default:
return NULL ;
}
}
void RsGxsPhotoAlbumItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
{
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_CAPTION, album.mCaption, "mCaption");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_CATEGORY, album.mCategory, "mCategory");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_DESCR, album.mDescription, "mDescription");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_HASH_TAG, album.mHashTags, "mHashTags");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_MSG, album.mOther, "mOther");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_PATH, album.mPhotoPath, "mPhotoPath");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_NAME, album.mPhotographer, "mPhotographer");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_DATE, album.mWhen, "mWhen");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_LOCATION, album.mWhere, "mWhere");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_PIC_TYPE, album.mThumbnail.type,"mThumbnail.type");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_CAPTION, album.mCaption, "mCaption");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_CATEGORY, album.mCategory, "mCategory");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_DESCR, album.mDescription, "mDescription");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_HASH_TAG, album.mHashTags, "mHashTags");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_MSG, album.mOther, "mOther");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_PATH, album.mPhotoPath, "mPhotoPath");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_NAME, album.mPhotographer, "mPhotographer");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_DATE, album.mWhen, "mWhen");
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_LOCATION, album.mWhere, "mWhere");
RsTlvBinaryDataRef b(RS_SERVICE_GXS_TYPE_PHOTO, album.mThumbnail.data, album.mThumbnail.size);
RsTypeSerializer::serial_process<RsTlvItem>(j, ctx, b, "thumbnail binary data") ;
album.mThumbnail.serial_process(j, ctx);
}
void RsGxsPhotoPhotoItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
{
@ -70,15 +65,13 @@ void RsGxsPhotoPhotoItem::serial_process(RsGenericSerializer::SerializeJob j,RsG
RsTypeSerializer::serial_process(j, ctx, TLV_TYPE_STR_PIC_AUTH, photo.mPhotographer, "mPhotographer");
RsTypeSerializer::serial_process(j, ctx, TLV_TYPE_STR_DATE, photo.mWhen, "mWhen");
RsTypeSerializer::serial_process(j, ctx, TLV_TYPE_STR_LOCATION, photo.mWhere, "mWhere");
RsTypeSerializer::serial_process(j, ctx, TLV_TYPE_STR_PIC_TYPE, photo.mThumbnail.type, "mThumbnail.type");
RsTlvBinaryDataRef b(RS_SERVICE_GXS_TYPE_PHOTO, photo.mThumbnail.data, photo.mThumbnail.size);
RsTypeSerializer::serial_process<RsTlvItem>(j, ctx, b, "mThumbnail") ;
photo.mThumbnail.serial_process(j, ctx);
}
void RsGxsPhotoCommentItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
{
RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_COMMENT,comment.mComment,"mComment");
RsTypeSerializer::serial_process<uint32_t>(j,ctx,comment.mCommentFlag,"mCommentFlag");
RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_COMMENT,comment.mComment,"mComment");
RsTypeSerializer::serial_process<uint32_t>(j,ctx,comment.mCommentFlag,"mCommentFlag");
}
void RsGxsPhotoAlbumItem::clear()
@ -92,13 +85,13 @@ void RsGxsPhotoAlbumItem::clear()
album.mPhotographer.clear();
album.mWhen.clear();
album.mWhere.clear();
album.mThumbnail.deleteImage();
album.mThumbnail.clear();
}
void RsGxsPhotoCommentItem::clear()
{
comment.mComment.clear();
comment.mCommentFlag = 0;
comment.mComment.clear();
comment.mCommentFlag = 0;
}
void RsGxsPhotoPhotoItem::clear()
@ -111,5 +104,5 @@ void RsGxsPhotoPhotoItem::clear()
photo.mPhotographer.clear();
photo.mWhen.clear();
photo.mWhere.clear();
photo.mThumbnail.deleteImage();
photo.mThumbnail.clear();
}

View file

@ -26,140 +26,100 @@
RsPhoto *rsPhoto = NULL;
const uint32_t RsPhoto::FLAG_MSG_TYPE_MASK = 0x000f;
const uint32_t RsPhoto::FLAG_MSG_TYPE_MASK = 0x000f;
const uint32_t RsPhoto::FLAG_MSG_TYPE_PHOTO_POST = 0x0001;
const uint32_t RsPhoto::FLAG_MSG_TYPE_PHOTO_COMMENT = 0x0002;
bool RsPhotoThumbnail::copyFrom(const RsPhotoThumbnail &nail)
{
if (data)
{
deleteImage();
}
if ((!nail.data) || (nail.size == 0))
{
return false;
}
size = nail.size;
type = nail.type;
data = (uint8_t *) rs_malloc(size);
if(data == NULL)
return false ;
memcpy(data, nail.data, size);
return true;
}
bool RsPhotoThumbnail::deleteImage()
{
if (data)
{
free(data);
data = NULL;
size = 0;
type.clear();
}
return true;
}
RsPhotoPhoto::RsPhotoPhoto()
:mSetFlags(0), mOrder(0), mMode(0), mModFlags(0)
:mSetFlags(0), mOrder(0), mMode(0), mModFlags(0)
{
return;
return;
}
RsPhotoAlbum::RsPhotoAlbum()
:mMode(0), mSetFlags(0), mModFlags(0)
:mMode(0), mSetFlags(0), mModFlags(0)
{
return;
return;
}
RsPhotoComment::RsPhotoComment()
: mComment(""), mCommentFlag(0) {
: mComment(""), mCommentFlag(0) {
}
RsPhotoComment::RsPhotoComment(const RsGxsPhotoCommentItem &comment)
: mComment(""), mCommentFlag(0) {
: mComment(""), mCommentFlag(0) {
*this = comment.comment;
(*this).mMeta = comment.meta;
*this = comment.comment;
(*this).mMeta = comment.meta;
}
std::ostream &operator<<(std::ostream &out, const RsPhotoPhoto &photo)
{
out << "RsPhotoPhoto [ ";
out << "Title: " << photo.mMeta.mMsgName;
out << "]";
return out;
out << "RsPhotoPhoto [ ";
out << "Title: " << photo.mMeta.mMsgName;
out << "]";
return out;
}
std::ostream &operator<<(std::ostream &out, const RsPhotoAlbum &album)
{
out << "RsPhotoAlbum [ ";
out << "Title: " << album.mMeta.mGroupName;
out << "]";
return out;
out << "RsPhotoAlbum [ ";
out << "Title: " << album.mMeta.mGroupName;
out << "]";
return out;
}
p3PhotoService::p3PhotoService(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs* gixs)
: RsGenExchange(gds, nes, new RsGxsPhotoSerialiser(), RS_SERVICE_GXS_TYPE_PHOTO, gixs, photoAuthenPolicy()),
mPhotoMutex(std::string("Photo Mutex"))
: RsGenExchange(gds, nes, new RsGxsPhotoSerialiser(), RS_SERVICE_GXS_TYPE_PHOTO, gixs, photoAuthenPolicy()),
mPhotoMutex(std::string("Photo Mutex"))
{
}
const std::string GXS_PHOTO_APP_NAME = "gxsphoto";
const uint16_t GXS_PHOTO_APP_MAJOR_VERSION = 1;
const uint16_t GXS_PHOTO_APP_MINOR_VERSION = 0;
const uint16_t GXS_PHOTO_MIN_MAJOR_VERSION = 1;
const uint16_t GXS_PHOTO_MIN_MINOR_VERSION = 0;
const uint16_t GXS_PHOTO_APP_MAJOR_VERSION = 1;
const uint16_t GXS_PHOTO_APP_MINOR_VERSION = 0;
const uint16_t GXS_PHOTO_MIN_MAJOR_VERSION = 1;
const uint16_t GXS_PHOTO_MIN_MINOR_VERSION = 0;
RsServiceInfo p3PhotoService::getServiceInfo()
{
return RsServiceInfo(RS_SERVICE_GXS_TYPE_PHOTO,
GXS_PHOTO_APP_NAME,
GXS_PHOTO_APP_MAJOR_VERSION,
GXS_PHOTO_APP_MINOR_VERSION,
GXS_PHOTO_MIN_MAJOR_VERSION,
GXS_PHOTO_MIN_MINOR_VERSION);
return RsServiceInfo(RS_SERVICE_GXS_TYPE_PHOTO,
GXS_PHOTO_APP_NAME,
GXS_PHOTO_APP_MAJOR_VERSION,
GXS_PHOTO_APP_MINOR_VERSION,
GXS_PHOTO_MIN_MAJOR_VERSION,
GXS_PHOTO_MIN_MINOR_VERSION);
}
uint32_t p3PhotoService::photoAuthenPolicy()
{
uint32_t policy = 0;
uint8_t flag = 0;
uint32_t policy = 0;
uint8_t flag = 0;
flag = GXS_SERV::MSG_AUTHEN_ROOT_PUBLISH_SIGN | GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN;
RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PUBLIC_GRP_BITS);
flag = GXS_SERV::MSG_AUTHEN_ROOT_PUBLISH_SIGN | GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN;
RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PUBLIC_GRP_BITS);
flag |= GXS_SERV::MSG_AUTHEN_CHILD_PUBLISH_SIGN;
RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::RESTRICTED_GRP_BITS);
RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PRIVATE_GRP_BITS);
flag |= GXS_SERV::MSG_AUTHEN_CHILD_PUBLISH_SIGN;
RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::RESTRICTED_GRP_BITS);
RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PRIVATE_GRP_BITS);
flag = GXS_SERV::GRP_OPTION_AUTHEN_AUTHOR_SIGN;
RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::GRP_OPTION_BITS);
flag = GXS_SERV::GRP_OPTION_AUTHEN_AUTHOR_SIGN;
RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::GRP_OPTION_BITS);
return policy;
return policy;
}
bool p3PhotoService::updated()
{
RsStackMutex stack(mPhotoMutex);
RsStackMutex stack(mPhotoMutex);
bool changed = (!mGroupChange.empty() || !mMsgChange.empty());
bool changed = (!mGroupChange.empty() || !mMsgChange.empty());
return changed;
return changed;
}
void p3PhotoService::service_tick()
@ -171,33 +131,34 @@ void p3PhotoService::service_tick()
void p3PhotoService::groupsChanged(std::list<RsGxsGroupId>& grpIds)
{
RsStackMutex stack(mPhotoMutex);
RsStackMutex stack(mPhotoMutex);
while(!mGroupChange.empty())
{
RsGxsGroupChange* gc = mGroupChange.back();
std::list<RsGxsGroupId>& gList = gc->mGrpIdList;
std::list<RsGxsGroupId>::iterator lit = gList.begin();
for(; lit != gList.end(); ++lit)
grpIds.push_back(*lit);
while(!mGroupChange.empty())
{
RsGxsGroupChange* gc = mGroupChange.back();
std::list<RsGxsGroupId>& gList = gc->mGrpIdList;
std::list<RsGxsGroupId>::iterator lit = gList.begin();
for(; lit != gList.end(); ++lit) {
grpIds.push_back(*lit);
}
mGroupChange.pop_back();
delete gc;
}
mGroupChange.pop_back();
delete gc;
}
}
void p3PhotoService::msgsChanged(GxsMsgIdResult& msgs)
{
RsStackMutex stack(mPhotoMutex);
RsStackMutex stack(mPhotoMutex);
while(!mMsgChange.empty())
{
RsGxsMsgChange* mc = mMsgChange.back();
msgs = mc->msgChangeMap;
mMsgChange.pop_back();
delete mc;
}
while(!mMsgChange.empty())
{
RsGxsMsgChange* mc = mMsgChange.back();
msgs = mc->msgChangeMap;
mMsgChange.pop_back();
delete mc;
}
}
@ -210,7 +171,8 @@ RsTokenService* p3PhotoService::getTokenService() {
bool p3PhotoService::getGroupList(const uint32_t& token,
std::list<RsGxsGroupId>& groupIds)
{
return RsGenExchange::getGroupList(token, groupIds);
bool okay = RsGenExchange::getGroupList(token, groupIds);
return okay;
}
@ -225,7 +187,8 @@ bool p3PhotoService::getMsgList(const uint32_t& token,
bool p3PhotoService::getGroupSummary(const uint32_t& token,
std::list<RsGroupMetaData>& groupInfo)
{
return RsGenExchange::getGroupMeta(token, groupInfo);
bool okay = RsGenExchange::getGroupMeta(token, groupInfo);
return okay;
}
@ -306,61 +269,59 @@ bool p3PhotoService::getPhoto(const uint32_t& token, PhotoResult& photos)
bool p3PhotoService::getPhotoComment(const uint32_t &token, PhotoCommentResult &comments)
{
GxsMsgDataMap msgData;
bool ok = RsGenExchange::getMsgData(token, msgData);
GxsMsgDataMap msgData;
bool ok = RsGenExchange::getMsgData(token, msgData);
if(ok)
{
GxsMsgDataMap::iterator mit = msgData.begin();
if(ok)
{
GxsMsgDataMap::iterator mit = msgData.begin();
for(; mit != msgData.end(); ++mit)
{
RsGxsGroupId grpId = mit->first;
std::vector<RsGxsMsgItem*>& msgItems = mit->second;
std::vector<RsGxsMsgItem*>::iterator vit = msgItems.begin();
for(; mit != msgData.end(); ++mit)
{
RsGxsGroupId grpId = mit->first;
std::vector<RsGxsMsgItem*>& msgItems = mit->second;
std::vector<RsGxsMsgItem*>::iterator vit = msgItems.begin();
for(; vit != msgItems.end(); ++vit)
{
RsGxsPhotoCommentItem* item = dynamic_cast<RsGxsPhotoCommentItem*>(*vit);
for(; vit != msgItems.end(); ++vit)
{
RsGxsPhotoCommentItem* item = dynamic_cast<RsGxsPhotoCommentItem*>(*vit);
if(item)
{
RsPhotoComment comment = item->comment;
comment.mMeta = item->meta;
comments[grpId].push_back(comment);
delete item;
}else
{
std::cerr << "Not a comment Item, deleting!" << std::endl;
delete *vit;
}
}
}
}
if(item)
{
RsPhotoComment comment = item->comment;
comment.mMeta = item->meta;
comments[grpId].push_back(comment);
delete item;
}else
{
std::cerr << "Not a comment Item, deleting!" << std::endl;
delete *vit;
}
}
}
}
return ok;
return ok;
}
RsPhotoComment& RsPhotoComment::operator=(const RsGxsPhotoCommentItem& comment)
{
*this = comment.comment;
return *this;
*this = comment.comment;
return *this;
}
bool p3PhotoService::getPhotoRelatedComment(const uint32_t &token, PhotoRelatedCommentResult &comments)
{
return RsGenExchange::getMsgRelatedDataT<RsGxsPhotoCommentItem, RsPhotoComment>(token, comments);
return RsGenExchange::getMsgRelatedDataT<RsGxsPhotoCommentItem, RsPhotoComment>(token, comments);
}
bool p3PhotoService::submitAlbumDetails(uint32_t& token, RsPhotoAlbum& album)
{
RsGxsPhotoAlbumItem* albumItem = new RsGxsPhotoAlbumItem();
albumItem->album = album;
albumItem->meta = album.mMeta;
RsGenExchange::publishGroup(token, albumItem);
return true;
RsGxsPhotoAlbumItem* albumItem = new RsGxsPhotoAlbumItem();
albumItem->album = album;
albumItem->meta = album.mMeta;
RsGenExchange::publishGroup(token, albumItem);
return true;
}
@ -368,28 +329,28 @@ bool p3PhotoService::submitAlbumDetails(uint32_t& token, RsPhotoAlbum& album)
void p3PhotoService::notifyChanges(std::vector<RsGxsNotify*>& changes)
{
RsStackMutex stack(mPhotoMutex);
RsStackMutex stack(mPhotoMutex);
std::vector<RsGxsNotify*>::iterator vit = changes.begin();
std::vector<RsGxsNotify*>::iterator vit = changes.begin();
for(; vit != changes.end(); ++vit)
{
RsGxsNotify* n = *vit;
RsGxsGroupChange* gc;
RsGxsMsgChange* mc;
if((mc = dynamic_cast<RsGxsMsgChange*>(n)) != NULL)
{
mMsgChange.push_back(mc);
}
else if((gc = dynamic_cast<RsGxsGroupChange*>(n)) != NULL)
{
mGroupChange.push_back(gc);
}
else
{
delete n;
}
}
for(; vit != changes.end(); ++vit)
{
RsGxsNotify* n = *vit;
RsGxsGroupChange* gc;
RsGxsMsgChange* mc;
if((mc = dynamic_cast<RsGxsMsgChange*>(n)) != NULL)
{
mMsgChange.push_back(mc);
}
else if((gc = dynamic_cast<RsGxsGroupChange*>(n)) != NULL)
{
mGroupChange.push_back(gc);
}
else
{
delete n;
}
}
}
bool p3PhotoService::submitPhoto(uint32_t& token, RsPhotoPhoto& photo)
@ -397,21 +358,20 @@ bool p3PhotoService::submitPhoto(uint32_t& token, RsPhotoPhoto& photo)
RsGxsPhotoPhotoItem* photoItem = new RsGxsPhotoPhotoItem();
photoItem->photo = photo;
photoItem->meta = photo.mMeta;
photoItem->meta.mMsgFlags = FLAG_MSG_TYPE_PHOTO_POST;
RsGenExchange::publishMsg(token, photoItem);
return true;
RsGenExchange::publishMsg(token, photoItem);
return true;
}
bool p3PhotoService::submitComment(uint32_t &token, RsPhotoComment &comment)
{
RsGxsPhotoCommentItem* commentItem = new RsGxsPhotoCommentItem();
commentItem->comment = comment;
commentItem->meta = comment.mMeta;
commentItem->meta.mMsgFlags = FLAG_MSG_TYPE_PHOTO_COMMENT;
RsGxsPhotoCommentItem* commentItem = new RsGxsPhotoCommentItem();
commentItem->comment = comment;
commentItem->meta = comment.mMeta;
commentItem->meta.mMsgFlags = FLAG_MSG_TYPE_PHOTO_COMMENT;
RsGenExchange::publishMsg(token, commentItem);
return true;
RsGenExchange::publishMsg(token, commentItem);
return true;
}
bool p3PhotoService::acknowledgeMsg(const uint32_t& token,
@ -429,12 +389,12 @@ bool p3PhotoService::acknowledgeGrp(const uint32_t& token,
bool p3PhotoService::subscribeToAlbum(uint32_t &token, const RsGxsGroupId &grpId, bool subscribe)
{
if(subscribe)
RsGenExchange::setGroupSubscribeFlags(token, grpId, GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED, GXS_SERV::GROUP_SUBSCRIBE_MASK);
else
RsGenExchange::setGroupSubscribeFlags(token, grpId, 0, GXS_SERV::GROUP_SUBSCRIBE_MASK);
if(subscribe)
RsGenExchange::setGroupSubscribeFlags(token, grpId, GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED, GXS_SERV::GROUP_SUBSCRIBE_MASK);
else
RsGenExchange::setGroupSubscribeFlags(token, grpId, 0, GXS_SERV::GROUP_SUBSCRIBE_MASK);
return true;
return true;
}

View file

@ -30,7 +30,7 @@
* #define POSTED_DEBUG 1
****/
RsPosted *rsPosted = NULL;
/*extern*/ RsPosted* rsPosted = nullptr;
/********************************************************************************/
/******************* Startup / Tick ******************************************/
@ -300,4 +300,35 @@ bool p3Posted::createPost(uint32_t &token, RsPostedPost &msg)
return true;
}
/********************************************************************************************/
bool p3Posted::getBoardsInfo(
const std::list<RsGxsGroupId>& boardsIds,
std::vector<RsPostedGroup>& channelsInfo )
{
uint32_t token;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
if( !requestGroupInfo(token, opts, boardsIds)
|| waitToken(token) != RsTokenService::COMPLETE ) return false;
return getGroupData(token, channelsInfo) && !channelsInfo.empty();
}
bool p3Posted::getBoardContent( const RsGxsGroupId& channelId,
const std::set<RsGxsMessageId>& contentsIds,
std::vector<RsPostedPost>& posts,
std::vector<RsGxsComment>& comments )
{
uint32_t token;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
GxsMsgReq msgIds;
msgIds[channelId] = contentsIds;
if( !requestMsgInfo(token, opts, msgIds) ||
waitToken(token) != RsTokenService::COMPLETE ) return false;
return getPostData(token, posts, comments);
}
RsPosted::~RsPosted() = default;
RsGxsPostedEvent::~RsGxsPostedEvent() = default;

View file

@ -39,15 +39,36 @@
class p3Posted: public p3PostBase, public RsPosted
{
public:
public:
p3Posted(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs* gixs);
virtual RsServiceInfo getServiceInfo();
virtual RsServiceInfo getServiceInfo();
protected:
virtual void notifyChanges(std::vector<RsGxsNotify*>& changes)
{
return p3PostBase::notifyChanges(changes);
}
public:
// Posted Specific DataTypes.
virtual bool getGroupData(const uint32_t &token, std::vector<RsPostedGroup> &groups);
virtual void receiveHelperChanges(std::vector<RsGxsNotify*>& changes)
{
return RsGxsIfaceHelper::receiveChanges(changes);
}
bool getBoardsInfo(
const std::list<RsGxsGroupId>& boardsIds,
std::vector<RsPostedGroup>& channelsInfo ) override;
bool getBoardContent(
const RsGxsGroupId& boardId,
const std::set<RsGxsMessageId>& contentsIds,
std::vector<RsPostedPost>& posts,
std::vector<RsGxsComment>& comments ) override;
virtual bool getGroupData(const uint32_t &token, std::vector<RsPostedGroup> &groups);
virtual bool getPostData(const uint32_t &token, std::vector<RsPostedPost> &posts, std::vector<RsGxsComment> &cmts);
virtual bool getPostData(const uint32_t &token, std::vector<RsPostedPost> &posts) { std::vector<RsGxsComment> cmts; return getPostData( token, posts, cmts);}
//Not currently used

View file

@ -164,12 +164,12 @@ int UdpStunner::grabExclusiveMode(std::string holder) /* returns seconds since
commsage = 1;
}
#ifdef DEBUG_UDP_STUNNER_FILTER
#endif
std::cerr << "UdpStunner::grabExclusiveMode() SUCCESS. last comms: " << commsage;
std::cerr << " ago";
std::cerr << std::endl;
std::cerr << "UdpStunner::grabExclusiveMode() Exclusive held by: " << mExclusiveHolder;
std::cerr << std::endl;
#endif
return commsage;
}
@ -181,13 +181,12 @@ int UdpStunner::releaseExclusiveMode(std::string holder, bool forceStun)
if (!mExclusiveMode)
{
#ifdef DEBUG_UDP_STUNNER_FILTER
#endif
std::cerr << "UdpStunner::cancelExclusiveMode() ERROR, not in exclusive Mode";
std::cerr << std::endl;
#endif
return 0;
}
rstime_t now = time(NULL);
mExclusiveMode = false;
if (forceStun)
{
@ -217,10 +216,11 @@ int UdpStunner::releaseExclusiveMode(std::string holder, bool forceStun)
}
#ifdef DEBUG_UDP_STUNNER_FILTER
#endif
rstime_t now = time(nullptr);
std::cerr << "UdpStunner::cancelExclusiveMode() Canceled. Was in ExclusiveMode for: " << now - mExclusiveModeTS;
std::cerr << " secs";
std::cerr << std::endl;
#endif
return 1;
}
@ -326,7 +326,7 @@ bool UdpStunner::locked_handleStunPkt(void *data, int size, struct sockaddr_in &
#endif
/* generate a response */
int len;
void *pkt = UdpStun_generate_stun_reply(&from, &len);
void *pkt = UdpStun_generate_stun_reply(&from, &len, data);
if (!pkt)
return false;
@ -485,7 +485,7 @@ bool UdpStun_response(void *stun_pkt, int size, struct sockaddr_in &addr)
return false;
}
if (htons(((uint16_t *) stun_pkt)[0]) != 0x0101)
if (htons(((uint16_t *) stun_pkt)[0]) != UdpStunner::STUN_BINDING_RESPONSE)
{
/* not a response */
return false;
@ -517,33 +517,38 @@ bool UdpStun_generate_stun_pkt(void *stun_pkt, int *len)
}
/* just the header */
((uint16_t *) stun_pkt)[0] = (uint16_t) htons(0x0001);
((uint16_t *) stun_pkt)[0] = (uint16_t) htons(UdpStunner::STUN_BINDING_REQUEST);
((uint16_t *) stun_pkt)[1] = (uint16_t) htons(20); /* only header */
/* transaction id - should be random */
((uint32_t *) stun_pkt)[1] = (uint32_t) htonl(0x0020);
((uint32_t *) stun_pkt)[2] = (uint32_t) htonl(0x0121);
((uint32_t *) stun_pkt)[3] = (uint32_t) htonl(0x0111);
((uint32_t *) stun_pkt)[4] = (uint32_t) htonl(0x1010);
/* RFC 3489
* The transaction ID is used to correlate requests and responses.
*
* RFC 5389 introduces a mmgic cokie at the location where preciously the transaction ID was located:
* In RFC 3489, this field was part of
* the transaction ID; placing the magic cookie in this location allows
* a server to detect if the client will understand certain attributes
* that were added in this revised specification.
*/
RsRandom::random_bytes(&((uint8_t *) stun_pkt)[4], 4 * sizeof (uint32_t));
*len = 20;
return true;
}
void *UdpStun_generate_stun_reply(struct sockaddr_in *stun_addr, int *len)
void *UdpStun_generate_stun_reply(struct sockaddr_in *stun_addr, int *len, const void *transId)
{
/* just the header */
void *stun_pkt = rs_malloc(28);
if(!stun_pkt)
return NULL ;
if(!stun_pkt)
return nullptr ;
((uint16_t *) stun_pkt)[0] = (uint16_t) htons(0x0101);
((uint16_t *) stun_pkt)[0] = (uint16_t) htons(UdpStunner::STUN_BINDING_RESPONSE);
((uint16_t *) stun_pkt)[1] = (uint16_t) htons(28); /* only header + 8 byte addr */
/* transaction id - should be random */
((uint32_t *) stun_pkt)[1] = (uint32_t) htonl(0x0f20);
((uint32_t *) stun_pkt)[2] = (uint32_t) htonl(0x0f21);
((uint32_t *) stun_pkt)[3] = (uint32_t) htonl(0x0f11);
((uint32_t *) stun_pkt)[4] = (uint32_t) htonl(0x1010);
/* RFC 3489
* The Binding Response MUST contain the same transaction ID contained in the Binding Request.
*/
memcpy(&((uint32_t *) stun_pkt)[1], &((uint32_t *) transId)[1], 4 * sizeof (uint32_t));
/* now add address
* 0 1 2 3
* <INET> <port>
@ -586,20 +591,20 @@ bool UdpStun_isStunPacket(void *data, int size)
return false;
}
if ((size == 20) && (0x0001 == ntohs(((uint16_t *) data)[0])))
if ((size == 20) && (UdpStunner::STUN_BINDING_REQUEST == ntohs(((uint16_t *) data)[0])))
{
#ifdef DEBUG_UDP_STUNNER_FILTER
std::cerr << "UdpStunner::isStunPacket() (size=20 & data[0]=0x0001) -> true";
std::cerr << "UdpStunner::isStunPacket() (size=20 & data[0]=STUN_BINDING_REQUEST) -> true";
std::cerr << std::endl;
#endif
/* request */
return true;
}
if ((size == 28) && (0x0101 == ntohs(((uint16_t *) data)[0])))
if ((size == 28) && (UdpStunner::STUN_BINDING_RESPONSE == ntohs(((uint16_t *) data)[0])))
{
#ifdef DEBUG_UDP_STUNNER_FILTER
std::cerr << "UdpStunner::isStunPacket() (size=28 & data[0]=0x0101) -> true";
std::cerr << "UdpStunner::isStunPacket() (size=28 & data[0]=STUN_BINDING_RESPONSE) -> true";
std::cerr << std::endl;
#endif
/* response */
@ -947,15 +952,15 @@ bool UdpStunner::locked_recvdStun(const struct sockaddr_in &remote, const str
if (remote.sin_addr.s_addr == extaddr.sin_addr.s_addr)
{
#ifdef DEBUG_UDP_STUNNER
#endif
std::cerr << "UdpStunner::locked_recvdStun() WARNING, BAD PEER: ";
std::cerr << "Stun Peer Returned its own address: " << rs_inet_ntoa(remote.sin_addr);
std::cerr << std::endl;
#endif
return false;
}
#endif
bool found = true;
bool found = false;
std::list<TouStunPeer>::iterator it;
for(it = mStunList.begin(); it != mStunList.end(); ++it)
{

View file

@ -30,10 +30,10 @@
#include "util/rsthreads.h"
#include <string>
/* UdpStun.
/**
* @brief The TouStunPeer class
* Stuns peers to determine external addresses.
*/
class TouStunPeer
{
public:
@ -53,10 +53,17 @@ class TouStunPeer
return;
}
/// id for identification
std::string id;
struct sockaddr_in remote, eaddr;
/// Remote address of the peer.
struct sockaddr_in remote;
/// Our external IP address as reported by the peer.
struct sockaddr_in eaddr;
/// true when a response was received in the past
bool response;
/// used to rate limit STUN requests
rstime_t lastsend;
/// fail counter for dead/bad peer detection (0 = good)
uint32_t failCount;
};
@ -65,6 +72,13 @@ class TouStunPeer
* #define UDPSTUN_ALLOW_LOCALNET 1
*/
/**
* @brief The UdpStunner class
* The UDP stunner implements the STUN protocol to determin the NAT type (behind that RS is usually running).
* It maintains a list of DHT peers that are regulary contacted.
*
* The actual NAT type determination logic is located in void pqiNetStateBox::determineNetworkState()
*/
class UdpStunner: public UdpSubReceiver
{
public:
@ -102,6 +116,12 @@ virtual int status(std::ostream &out);
/* monitoring / updates */
int tick();
/*
* based on RFC 3489
*/
static constexpr uint16_t STUN_BINDING_REQUEST = 0x0001;
static constexpr uint16_t STUN_BINDING_RESPONSE = 0x0101;
private:
bool checkStunDesired();
@ -123,7 +143,7 @@ bool locked_checkExternalAddress();
struct sockaddr_in eaddr; /* external addr */
bool eaddrKnown;
bool eaddrKnown;
bool eaddrStable; /* if true then usable. if false -> Symmettric NAT */
rstime_t eaddrTime;
@ -143,13 +163,19 @@ bool locked_checkExternalAddress();
#endif
/// The UDP stunner will only (actively) contact it's peers when mPassiveStunMode is false. (has priority over mForceRestun
bool mPassiveStunMode;
uint32_t mTargetStunPeriod;
/// Time between STUNs
uint32_t mTargetStunPeriod;
/// Rate that determines how often STUN attempts are successfull
double mSuccessRate;
/// Some variables used for tracking who and when exclusive mode is enabled
bool mExclusiveMode; /* when this is switched on, the stunner stays silent (and extAddr is maintained) */
rstime_t mExclusiveModeTS;
std::string mExclusiveHolder;
/// force a STUN immediately
bool mForceRestun;
};
@ -158,7 +184,14 @@ bool locked_checkExternalAddress();
bool UdpStun_isStunPacket(void *data, int size);
bool UdpStun_response(void *stun_pkt, int size, struct sockaddr_in &addr);
void *UdpStun_generate_stun_reply(struct sockaddr_in *stun_addr, int *len);
/**
* @brief UdpStun_generate_stun_reply Generates a STUN reply package.
* @param stun_addr The address to set in the response field.
* @param len Lenght of the generated package (always 28).
* @param transId The transaction ID of the request package.
* @return Pointer to the generated reply package.
*/
void *UdpStun_generate_stun_reply(struct sockaddr_in *stun_addr, int *len, const void* transId);
bool UdpStun_generate_stun_pkt(void *stun_pkt, int *len);
#endif