'will call self.packetHandler(udp=Packet(),data=data)
(see Packet() for Packet object common attributes)
udp.pkt will contain the raw IP data
data will contain the decoded UDP payload
State tracking:
only if connectionHandler or blobHandler is present
and packetHandler is not present
UDPDecoder will call:
self.connectionInitHandler(conn=Connection())
when UDP state is established
(see Connection() for Connection object attributes)
self.blobHandler(conn=Connection(),blob=Blob())
when stream direction switches (if following stream)
blob=(see Blob() objects)
self.connectionHandler(conn=Connection())
when UDP state is flushed (if following stream)
state is flushed when stale or when maxblobs is exceeded
if maxblobs exceeded, current data will go into new connection
self.connectionCloseHandler(conn=Connection())
when state is discarded (always)'

def UDP(self, addr, data, pkt, ts=None, **kwargs):

    self.decodedbytes += len(data)
    self.count += 1
    try:
        if self.isPacketHandlerPresent:
            return self.packetHandler(udp=Packet(self, addr, pkt=pkt, ts=ts, **kwargs), data=data)
        conn = self.find(addr)
        if (not conn):
            conn = self.track(addr, ts=ts, state='init', **kwargs)
        if (conn.nextoffset['cs'] is None):
            conn.nextoffset['cs'] = 0
        if (conn.nextoffset['sc'] is None):
            conn.nextoffset['sc'] = 0
        self.track(addr, data, ts, **kwargs)
    except Exception as e:
        self._exc(e)
