Browse Source

now testing for valid callsigns

master
Tom Early 12 months ago
parent
commit
c133c39df0
  1. 5
      callsign.cpp
  2. 1
      callsign.h
  3. 27
      config/mrefd.interlink
  4. 89
      m17protocol.cpp
  5. 6
      m17protocol.h

5
callsign.cpp

@ -131,11 +131,6 @@ void CCallsign::SetModule(char m)
CSIn(call);
}
bool CCallsign::IsValid() const
{
return true;
}
std::ostream &operator<<(std::ostream &stream, const CCallsign &call)
{
stream << call.cs;

1
callsign.h

@ -38,7 +38,6 @@ public:
bool HasSameCallsignWithWildcard(const CCallsign &callsign) const;
bool HasModule() const { return ('A' <= cs[9] && cs[9] <= 'Z'); }
void SetModule(char m);
bool IsValid() const;
friend std::ostream &operator<<(std::ostream &stream, const CCallsign &call);
bool HasSameCallsign(const CCallsign &call) const;
private:

27
config/mrefd.interlink

@ -2,13 +2,30 @@
# M17 interlink file
#
# one line per entry
# each entry specifies a remote M17 reflector to peer with
# each entry specifies a remote M17 Reflector to peer with
# format:
# <M17 callsign> <ip> <local module><remote module>
# <M17 callsign> <ip> <list of shared modules>
# example:
# M17USA 158.64.26.132 BD
# M17-ABC 44.123.213.112 ACD
# M17-XYZ 2600:400:bc03::100 ACD
#
# In the above example, this reflector would link modules A, C and D
# with both M17-ABC and M17-XYZ. This example implies both this
# reflector and M17-XYZ support IPv6.
#
# These remote reflectors must list this reflector and modules
# in their interlink file for the link to be established
#
# Every reflector in an interlink group must link to every other
# reflector in the group else clients in a group may not hear every
# client in the group.
#
# A single reflector can participate in multiple groups.
# For example, there could be one group with four different reflectors
# sharing modules A, C and D and another group with three other
# reflectors sharing just module F.
#
# Each module can only be in a single group.
#
# This would request the local module B to be linked with M17USA D
# IPv6 address are supported as well
#
#############################################################################

89
m17protocol.cpp

@ -35,6 +35,9 @@
bool CM17Protocol::Initialize(int ptype, const uint16_t port, const bool has_ipv4, const bool has_ipv6)
{
peerRegEx = std::regex("^M17-([A-Z0-9]){3,3}[ ][A-Z]$", std::regex::extended);
clientRegEx = std::regex("^[0-9]{0,1}[A-Z]{1,2}[0-9][A-Z]{1,4}(()|[ ]*[A-Z]|([-/\\.][A-Z0-9]*))$", std::regex::extended);
// base class
if (! CProtocol::Initialize(ptype, port, has_ipv4, has_ipv6))
return false;
@ -132,10 +135,6 @@ void CM17Protocol::Task(void)
g_Reflector.ReleasePeers();
}
}
else
{
Dump("Unknown packet", buf, len);
}
break;
case 11:
if ( IsValidConnect(buf, cs, &mod) )
@ -176,36 +175,65 @@ void CM17Protocol::Task(void)
case 10:
if ( IsValidKeepAlive(buf, cs) )
{
// find all clients with that callsign & ip and keep them alive
CClients *clients = g_Reflector.GetClients();
auto it = clients->begin();
std::shared_ptr<CClient>client = nullptr;
while (nullptr != (client = clients->FindNextClient(cs, ip, PROTOCOL_M17, it)))
if (cs.GetCS(4).compare("M17-")) {
// find all clients with that callsign & ip and keep them alive
CClients *clients = g_Reflector.GetClients();
auto it = clients->begin();
std::shared_ptr<CClient>client = nullptr;
while (nullptr != (client = clients->FindNextClient(cs, ip, PROTOCOL_M17, it)))
{
client->Alive();
}
g_Reflector.ReleaseClients();
}
else
{
client->Alive();
// find peer
CPeers *peers = g_Reflector.GetPeers();
std::shared_ptr<CPeer>peer = peers->FindPeer(ip, PROTOCOL_M17);
if ( peer != nullptr )
{
// keep it alive
peer->Alive();
}
g_Reflector.ReleasePeers();
}
g_Reflector.ReleaseClients();
}
else if ( IsValidDisconnect(buf, cs) )
{
std::cout << "Disconnect packet from " << cs << " at " << ip << std::endl;
// find client & remove it
CClients *clients = g_Reflector.GetClients();
std::shared_ptr<CClient>client = clients->FindClient(ip, PROTOCOL_M17);
if ( client != nullptr )
if (cs.GetCS(4).compare("M17-")) {
// find the regular client & remove it
CClients *clients = g_Reflector.GetClients();
std::shared_ptr<CClient>client = clients->FindClient(ip, PROTOCOL_M17);
if ( client != nullptr )
{
// ack disconnect packet
EncodeDisconnectedPacket(buf);
Send(buf, 4, ip);
// and remove it
clients->RemoveClient(client);
}
g_Reflector.ReleaseClients();
}
else
{
// ack disconnect packet
EncodeDisconnectedPacket(buf);
Send(buf, 4, ip);
// and remove it
clients->RemoveClient(client);
// find the peer and remove it
CPeers *peers = g_Reflector.GetPeers();
std::shared_ptr<CPeer>peer = peers->FindPeer(ip, PROTOCOL_M17);
if ( peer )
{
// remove it from reflector peer list
// this also remove all concerned clients from reflector client list
// and delete them
peers->RemovePeer(peer);
}
g_Reflector.ReleasePeers();
}
g_Reflector.ReleaseClients();
}
else if ( IsValidNAcknowledge(buf, cs))
{
std::cout << "NACK packet received from " << cs << " at " << ip << std::endl;
}
break;
default:
@ -456,6 +484,13 @@ void CM17Protocol::OnFirstPacketIn(std::unique_ptr<CPacket> &packet, const CIp &
}
}
////////////////////////////////////////////////////////////////////////////////////////
// callsign helper
bool CM17Protocol::IsValidCallsign(const CCallsign &cs)
{
return std::regex_match(cs.GetCS(), clientRegEx) || std::regex_match(cs.GetCS(), peerRegEx);
}
////////////////////////////////////////////////////////////////////////////////////////
// packet decoding helpers
@ -464,7 +499,7 @@ bool CM17Protocol::IsValidConnect(const uint8_t *buf, CCallsign &cs, char *mod)
if (0 == memcmp(buf, "CONN", 4))
{
cs.CodeIn(buf + 4);
if (cs.IsValid())
if (IsValidCallsign(cs))
{
*mod = buf[10];
if (IsLetter(*mod))
@ -479,7 +514,7 @@ bool CM17Protocol::IsValidDisconnect(const uint8_t *buf, CCallsign &cs)
if (0 == memcmp(buf, "DISC", 4))
{
cs.CodeIn(buf + 4);
if (cs.IsValid())
if (IsValidCallsign(cs))
{
return true;
}
@ -492,7 +527,7 @@ bool CM17Protocol::IsValidKeepAlive(const uint8_t *buf, CCallsign &cs)
if ('P' == buf[0] && ('I' == buf[1] || 'O' == buf[1]) && 'N' == buf[2] && 'G' == buf[3])
{
cs.CodeIn(buf + 4);
if (cs.IsValid())
if (IsValidCallsign(cs))
{
return true;
}
@ -507,7 +542,7 @@ bool CM17Protocol::IsValidPacket(const uint8_t *buf, bool is_internal, std::uniq
// create packet
packet = std::unique_ptr<CPacket>(new CPacket(buf, is_internal));
// check validity of packet
if ( packet->GetSourceCallsign().IsValid() )
if ( IsValidCallsign( packet->GetSourceCallsign() ) )
{ // looks like a valid source
return true;
}

6
m17protocol.h

@ -22,6 +22,8 @@
#pragma once
#include <regex>
#include "timepoint.h"
#include "protocol.h"
#include "packet.h"
@ -47,6 +49,9 @@ protected:
void HandlePeerLinks(void);
void HandleKeepalives(void);
// callsign helper
bool IsValidCallsign(const CCallsign &);
// stream helpers
void OnFirstPacketIn(std::unique_ptr<CPacket> &, const CIp &);
@ -75,5 +80,6 @@ protected:
CTimePoint m_LastPeersLinkTime;
private:
std::regex clientRegEx, peerRegEx;
CCRC crc;
};
Loading…
Cancel
Save