#include "UdpPacketListener.h"
#include "UdpPacketListener.c7"
#include "Stones/SUdpPacket.h"
#include "Gled/GThread.h"
#include <cerrno>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
ClassImp(UdpPacketListener);
void UdpPacketListener::_init()
{
mSuckPort = 9930;
mSocket = 0;
mSuckerThread = 0;
}
UdpPacketListener::UdpPacketListener(const Text_t* n, const Text_t* t) :
UdpPacketSource(n, t)
{
_init();
}
UdpPacketListener::~UdpPacketListener()
{}
void* UdpPacketListener::tl_Suck(UdpPacketListener* s)
{
s->Suck();
s->mSuckerThread = 0;
return 0;
}
void UdpPacketListener::Suck()
{
static const Exc_t _eh("UdpPacketListener::Suck ");
if ((mSocket = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
throw _eh + "socket failed: " + strerror(errno);
{
struct addrinfo *result;
struct addrinfo hints;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV;
int error = getaddrinfo(0, TString::Format("%hu", mSuckPort), &hints, &result);
if (error != 0)
throw _eh + "getaddrinfo failed: " + gai_strerror(error);
if (bind(mSocket, result->ai_addr, result->ai_addrlen) == -1)
throw _eh + "bind failed: " + strerror(errno);
freeaddrinfo(result);
}
const int buf_size = 65536;
unsigned char buf[buf_size];
int flags = 0;
struct sockaddr_in addr;
socklen_t slen = sizeof(sockaddr_in);
while (true)
{
ssize_t len = recvfrom(mSocket, buf, buf_size, flags,
(sockaddr*) &addr, &slen);
if (len == -1)
{
ISwarn(_eh + "recvfrom failed: " + strerror(errno));
continue;
}
else if (len == 0)
{
ISwarn(_eh + "recvfrom returned 0, not expected.");
continue;
}
GTime recv_time(GTime::I_Now);
UInt_t in4a = addr.sin_addr.s_addr;
UShort_t port = ntohs(addr.sin_port);
UChar_t *addr_p = (UChar_t*) &addr.sin_addr.s_addr;
SUdpPacket *p = new SUdpPacket(recv_time, addr_p, 4, port, buf, len);
if (G_DEBUG > 1)
{
Char_t hn_buf[64];
getnameinfo((sockaddr*) &addr, slen, hn_buf, 64, 0, 0, NI_DGRAM);
TString fqhn(hn_buf);
fqhn.ToLower();
char *foo = (char*) &in4a;
printf("Message from: %hhu.%hhu.%hhu.%hhu:%hu, fqdn=%s, len=%zd\n",
foo[0], foo[1], foo[2], foo[3], port, hn_buf, len);
}
mConsumerSet.DeliverToQueues(p);
}
}
void UdpPacketListener::StartAllServices()
{
static const Exc_t _eh("UdpPacketListener::StartAllServices ");
{
GLensReadHolder _lck(this);
if (mSuckerThread)
throw _eh + "already running.";
mSuckerThread = new GThread("UdpPacketListener-Sucker",
(GThread_foo) tl_Suck, this,
false);
mSuckerThread->SetNice(0);
}
mSuckerThread->Spawn();
}
void UdpPacketListener::StopAllServices()
{
static const Exc_t _eh("UdpPacketListener::StopAllServices ");
GThread *thr = 0;
{
GLensReadHolder _lck(this);
if ( ! GThread::IsValidPtr(mSuckerThread))
throw _eh + "not running.";
thr = mSuckerThread;
GThread::InvalidatePtr(mSuckerThread);
}
thr->Cancel();
thr->Join();
close(mSocket);
{
GLensReadHolder _lck(this);
mSuckerThread = 0;
mSocket = 0;
}
}
UdpPacketListener.cxx:100 UdpPacketListener.cxx:101 UdpPacketListener.cxx:102 UdpPacketListener.cxx:103 UdpPacketListener.cxx:104 UdpPacketListener.cxx:105 UdpPacketListener.cxx:106 UdpPacketListener.cxx:107 UdpPacketListener.cxx:108 UdpPacketListener.cxx:109 UdpPacketListener.cxx:110 UdpPacketListener.cxx:111 UdpPacketListener.cxx:112 UdpPacketListener.cxx:113 UdpPacketListener.cxx:114 UdpPacketListener.cxx:115 UdpPacketListener.cxx:116 UdpPacketListener.cxx:117 UdpPacketListener.cxx:118 UdpPacketListener.cxx:119 UdpPacketListener.cxx:120 UdpPacketListener.cxx:121 UdpPacketListener.cxx:122 UdpPacketListener.cxx:123 UdpPacketListener.cxx:124 UdpPacketListener.cxx:125 UdpPacketListener.cxx:126 UdpPacketListener.cxx:127 UdpPacketListener.cxx:128 UdpPacketListener.cxx:129 UdpPacketListener.cxx:130 UdpPacketListener.cxx:131 UdpPacketListener.cxx:132 UdpPacketListener.cxx:133 UdpPacketListener.cxx:134 UdpPacketListener.cxx:135 UdpPacketListener.cxx:136 UdpPacketListener.cxx:137 UdpPacketListener.cxx:138 UdpPacketListener.cxx:139 UdpPacketListener.cxx:140 UdpPacketListener.cxx:141 UdpPacketListener.cxx:142 UdpPacketListener.cxx:143 UdpPacketListener.cxx:144 UdpPacketListener.cxx:145 UdpPacketListener.cxx:146 UdpPacketListener.cxx:147 UdpPacketListener.cxx:148 UdpPacketListener.cxx:149 UdpPacketListener.cxx:150 UdpPacketListener.cxx:151 UdpPacketListener.cxx:152 UdpPacketListener.cxx:153 UdpPacketListener.cxx:154 UdpPacketListener.cxx:155 UdpPacketListener.cxx:156 UdpPacketListener.cxx:157 UdpPacketListener.cxx:158 UdpPacketListener.cxx:159 UdpPacketListener.cxx:160 UdpPacketListener.cxx:161 UdpPacketListener.cxx:162 UdpPacketListener.cxx:163 UdpPacketListener.cxx:164 UdpPacketListener.cxx:165 UdpPacketListener.cxx:166 UdpPacketListener.cxx:167 UdpPacketListener.cxx:168 UdpPacketListener.cxx:169 UdpPacketListener.cxx:170 UdpPacketListener.cxx:171 UdpPacketListener.cxx:172 UdpPacketListener.cxx:173 UdpPacketListener.cxx:174 UdpPacketListener.cxx:175 UdpPacketListener.cxx:176 UdpPacketListener.cxx:177 UdpPacketListener.cxx:178 UdpPacketListener.cxx:179 UdpPacketListener.cxx:180 UdpPacketListener.cxx:181 UdpPacketListener.cxx:182 UdpPacketListener.cxx:183 UdpPacketListener.cxx:184 UdpPacketListener.cxx:185 UdpPacketListener.cxx:186 UdpPacketListener.cxx:187 UdpPacketListener.cxx:188 UdpPacketListener.cxx:189