#ifndef RS_UDP_STUN_H #define RS_UDP_STUN_H /* * tcponudp/udpstunner.h * * libretroshare. * * Copyright 2010 by Robert Fernie * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License Version 3 as published by the Free Software Foundation. * * 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA. * * Please report all bugs and problems to "retroshare@lunamutt.com". * */ #include #include "tcponudp/rsudpstack.h" #include "util/rsthreads.h" #include /* UdpStun. * Stuns peers to determine external addresses. */ class TouStunPeer { public: TouStunPeer() :response(false), lastsend(0), failCount(0) { eaddr.sin_addr.s_addr = 0; eaddr.sin_port = 0; return; } TouStunPeer(std::string id_in, const struct sockaddr_in &addr) :id(id_in), remote(addr), response(false), lastsend(0), failCount(0) { eaddr.sin_addr.s_addr = 0; eaddr.sin_port = 0; return; } std::string id; struct sockaddr_in remote, eaddr; bool response; time_t lastsend; uint32_t failCount; }; class UdpStunner: public UdpSubReceiver { public: UdpStunner(UdpPublisher *pub); virtual ~UdpStunner() { return; } bool setStunKeepAlive(uint32_t required); bool addStunPeer(const struct sockaddr_in &remote, const char *peerid); bool getStunPeer(int idx, std::string &id, struct sockaddr_in &remote, struct sockaddr_in &eaddr, uint32_t &failCount, time_t &lastSend); bool checkStunKeepAlive(); bool needStunPeers(); bool externalAddr(struct sockaddr_in &remote, uint8_t &stable); /* Packet IO */ virtual int recvPkt(void *data, int size, struct sockaddr_in &from); virtual int status(std::ostream &out); /* monitoring / updates */ int tick(); private: /* STUN handling */ bool locked_handleStunPkt(void *data, int size, struct sockaddr_in &from); int doStun(struct sockaddr_in stun_addr); /* stun keepAlive */ bool locked_printStunList(); bool locked_recvdStun(const struct sockaddr_in &remote, const struct sockaddr_in &extaddr); bool locked_checkExternalAddress(); bool storeStunPeer(const struct sockaddr_in &remote, const char *peerid, bool sent); RsMutex stunMtx; /* for all class data (below) */ struct sockaddr_in eaddr; /* external addr */ bool eaddrKnown; bool eaddrStable; /* if true then usable. if false -> Symmettric NAT */ time_t eaddrTime; bool mStunKeepAlive; time_t mStunLastRecv; time_t mStunLastSend; std::list mStunList; /* potentials */ }; /* generic stun functions */ 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); bool UdpStun_generate_stun_pkt(void *stun_pkt, int *len); #endif