Initial add of raet backend libs

This commit is contained in:
Thomas S Hatch 2014-02-03 16:44:13 -07:00
parent 2a7c10fe5b
commit d2f3addfd5
6 changed files with 938 additions and 0 deletions

View File

@ -0,0 +1,7 @@
""" shrub modules"""
#print "\nPackage at%s" % __path__[0]
__all__ = ['raet',]
for m in __all__:
exec "from . import %s" % m #relative import

View File

@ -0,0 +1,137 @@
# Shrub dev FloScript
house shrub
init .raet.media.address to host "" port 7532
init raet.packet.tx.meta to hk 0 hl 0 nk 0 nl 0 bk 1 bl 0 tk 0 tl 0 \
dh "127.0.0.1" dp 7533
init raet.packet.tx.head to hk 0 hl 0 vn 0 \
sd 10 dd 20 cf 0 mf 0 si 1 ti 1 \
sk 0 pk 0 bf 0 oi 0 dt 0 sn 0 sc 1 pf 0 af 0 \
nk 0 nl 0 bk 0 bl 0 tk 0 tl 0
init raet.packet.tx.neck to pack ""
init raet.packet.tx.body to mid "shrubbery" fun "dumb" foo "bar"
init raet.packet.tx.tail to pack ""
init raet.packet.tx.pack to value ""
init raet.packet.rx.pack to value ""
framer raeter be active first start
frame start
do raet server per inode ".raet.media."
exit
do raet server closer per inode ".raet.media."
framer shrubber be active first start
frame start
go next
frame compose
enter
do raet composer per inode ".raet.packet.tx."
go next
frame pack
enter
do raet packer per inode ".raet.packet.tx."
go next
frame transmit
#copy .raet.packet.tx.pack into .raet.packet.rx.pack
enter
do raet transmitter per inode ".raet.packet.tx."
go next
frame receive
do raet receiver per inode ".raet.packet.rx."
go next if update .raet.packet.rx.data
frame parse
enter
do raet parser per inode ".raet.packet.rx"
go next
frame abort
bid stop all
logger logger to log/ flush 1
log outbody to outbody on fifo
loggee outlog .raet.packet.tx.outlog
log txraw to txraw on fifo
loggee txlog .raet.media.txlog
log rxraw to rxraw on fifo
loggee rxlog .raet.media.rxlog
log inbody to inbody on fifo
loggee inlog .raet.packet.rx.inlog
house bush
init .raet.media.address to host "" port 7533
init raet.packet.tx.meta to hk 0 hl 0 nk 0 nl 0 bk 1 bl 0 tk 0 tl 0 \
dh "127.0.0.1" dp 7532
init raet.packet.tx.head to hk 0 hl 0 vn 0 \
sd 10 dd 20 cf 0 mf 0 si 1 ti 1 \
sk 0 pk 0 bf 0 oi 0 dt 0 sn 0 sc 1 pf 0 af 0 \
nk 0 nl 0 bk 0 bl 0 tk 0 tl 0
init raet.packet.tx.neck to pack ""
init raet.packet.tx.body to mid "bushery" fun "doh" foo "baz"
init raet.packet.tx.tail to pack ""
init raet.packet.tx.pack to value ""
init raet.packet.rx.pack to value ""
framer ratter be active first start
frame start
do raet server per inode ".raet.media."
exit
do raet server closer per inode ".raet.media."
framer busher be active first start
frame start
go next
frame compose
enter
do raet composer per inode ".raet.packet.tx."
go next
frame pack
enter
do raet packer per inode ".raet.packet.tx."
go next
frame transmit
#copy .raet.packet.tx.pack into .raet.packet.rx.pack
enter
do raet transmitter per inode ".raet.packet.tx."
go next
frame receive
do raet receiver per inode ".raet.packet.rx."
go next if update .raet.packet.rx.data
frame parse
enter
do raet parser per inode ".raet.packet.rx"
go next
frame abort
bid stop all
logger logger to log/ flush 1
log outbody to outbody on fifo
loggee outlog .raet.packet.tx.outlog
log txraw to txraw on fifo
loggee txlog .raet.media.txlog
log rxraw to rxraw on fifo
loggee rxlog .raet.media.rxlog
log inbody to inbody on fifo
loggee inlog .raet.packet.rx.inlog

View File

@ -0,0 +1,12 @@
""" raet modules
__init__.py file for raet package
"""
#print "\nPackage at%s" % __path__[0]
__all__ = ['packeting', 'stacking', 'raeting']
for m in __all__:
exec "from . import %s" % m #relative import

View File

@ -0,0 +1,306 @@
""" packeting.py raet packet behaviors
See raeting.py for data format and packet field details.
Data format. The data from which a packet is created is a nested dict of dicts.
What fields are included in a packed head, neck, body is dependent
on the header kind, service kind, packet kind and defaults.
To minimize lenght of JSON headers if field missing then the default is assumed
data =
{
meta: dict of meta data about packet
{
}
head: dict of header fields
{
pack: packed version of header
}
neck: dict of authentication fields
{
pack: packed version of neck
}
body: dict of body fields
{
pack: packed version of body
}
pack: packed version of whole packet on tx and raw packet on rx
}
"""
#print "module %s" % __name__
from collections import deque
try:
import simplejson as json
except ImportError:
import json
from ioflo.base.odicting import odict
from ioflo.base.globaling import *
from ioflo.base import aiding
from ioflo.base import storing
from ioflo.base import deeding
from ioflo.base.consoling import getConsole
console = getConsole()
from . import raeting
def CreateInstances(store):
""" Create action instances. Recreate with each new house after clear registry
"""
ComposerRaet(name='raetComposer', store=store).ioinits.update(
data=odict(ipath='data', ival=odict(), iown='True'),
meta='meta',
head='head',
neck='neck',
body='body',
tail='tail')
PackerRaet(name='raetPacker', store=store).ioinits.update(
data=odict(ipath='data', ival=odict(), iown=True),
outlog=odict(ipath='outlog', ival=odict(), iown=True),)
ParserRaet(name='raetParser', store=store).ioinits.update(
data=odict(ipath='data', ival=odict(), iown=True),
inlog=odict(ipath='inlog', ival=odict(), iown=True),)
TransmitterRaet(name='raetTransmitter', store=store).ioinits.update(
data='data',
txes=odict(ipath='.raet.media.txes', ival=deque()),)
ReceiverRaet(name='raetReceiver', store=store).ioinits.update(
data='data',
rxes=odict(ipath='.raet.media.rxes', ival=deque()), )
ServerRaet(name='raetServer', store=store).ioinits.update(
txes=odict(ipath='txes', ival=deque(), iown=True),
rxes=odict(ipath='rxes', ival=deque(), iown=True),
connection=odict(ipath='connection', ival=None, iown=True),
address=odict(ipath='address', ival=odict(host='', port=7530, ha=None)),
txlog=odict(ipath='txlog', ival=odict(), iown=True),
rxlog=odict(ipath='rxlog', ival=odict(), iown=True), )
CloserServerRaet(name='raetServerCloser', store=store).ioinits.update(
connection=odict(ipath='connection', ival=None))
class ComposerRaet(deeding.ParamDeed):
""" ComposerRaet creates packet data as nested dicts from fields in
share parms meta, head, neck, body, tail
inherited attributes
.name is actor name string
.store is data store ref
.ioinits is dict of io init data for initio
._parametric is flag for initio to not create attributes
"""
Ioinits = odict(
data=odict(ipath='data', ival=odict(), iown='True'),
meta='meta',
head='head',
neck='neck',
body='body',
tail='tail')
def action(self, data, meta, head, neck, body, tail, **kwa):
""" Build packet data from data section shares
"""
dat = raeting.defaultData()
dat['meta'].update(raeting.META_DEFAULTS)
dat['meta'].update(meta.items())
dat['head'].update(raeting.HEAD_DEFAULTS)
dat['head'].update(head.items())
dat['neck'].update(neck.items())
dat['body'].update(data=odict(body.items()))
dat['tail'].update(tail.items())
data.value = dat
return None
class PackerRaet(deeding.ParamDeed):
""" PackerRaet creates a new packed RAET packet from data and fills in pack field
inherited attributes
.name is actor name string
.store is data store ref
.ioinits is dict of io init data for initio
._parametric is flag for initio to not create attributes
"""
Ioinits = odict(
data=odict(ipath='data', ival=odict(), iown=True),
outlog=odict(ipath='outlog', ival=odict(), iown=True),)
def action(self, data, outlog, **kwa):
""" Build packet from data"""
if data.value:
raeting.packPacket(data.value)
data.stampNow()
outlog.value[(data.value['meta']['dh'], data.value['meta']['dp'])] = data.value['body'].get('data', {})
return None
class ParserRaet(deeding.ParamDeed):
""" ParserRaet parses a packed RAET packet from pack and fills in data
inherited attributes
.name is actor name string
.store is data store ref
.ioinits is dict of io init data for initio
._parametric is flag for initio to not create attributes
"""
Ioinits = odict(
data=odict(ipath='data', ival=odict(), iown=True),
inlog=odict(ipath='inlog', ival=odict(), iown=True),)
def action(self, data, inlog, **kwa):
""" Parse packet from raw packed"""
if data.value:
data.value = raeting.defaultData(data.value)
rest = raeting.parsePacket(data.value)
data.stampNow()
inlog.value[(data.value['meta']['sh'], data.value['meta']['sp'])] = data.value['body'].get('data', {})
return None
class TransmitterRaet(deeding.ParamDeed):
""" TransmitterRaet pushes packed packet in onto txes transmit deque and assigns
destination ha from meta data
inherited attributes
.name is actor name string
.store is data store ref
.ioinits is dict of io init data for initio
._parametric is flag for initio to not create attributes
"""
Ioinits = odict(
data='data',
txes=odict(ipath='.raet.media.txes', ival=deque()),)
def action(self, data, txes, **kwa):
""" """
if data.value:
da = (data.value['meta']['dh'], data.value['meta']['dp'])
txes.value.append((data.value['pack'], da))
return None
class ReceiverRaet(deeding.ParamDeed):
""" ReceiverRaet pulls packet from rxes deque and puts into new data
and assigns meta data source ha using recieved ha
inherited attributes
.name is actor name string
.store is data store ref
.ioinits is dict of io init data for initio
._parametric is flag for initio to not create attributes
"""
Ioinits = odict(
data='data',
rxes=odict(ipath='.raet.media.rxes', ival=deque()), )
def action(self, data, rxes, **kwa):
""" """
if rxes.value:
rx, sa, da = rxes.value.popleft()
data.value = raeting.defaultData()
data.value['pack'] = rx
data.value['meta']['sh'], data.value['meta']['sp'] = sa
data.value['meta']['dh'], data.value['meta']['dp'] = da
return None
class ServerRaet(deeding.ParamDeed):
""" ServerRaet transmits and recieves udp packets from txes and rxes deques
using sh, sp fields in sa server address (server host, server port) to receive on.
Server is nonblocking socket connection
inherited attributes
.name is actor name string
.store is data store ref
.ioinits is dict of io init data for initio
._parametric is flag for initio to not create attributes
"""
Ioinits = odict(
txes=odict(ipath='txes', ival=deque(), iown=True),
rxes=odict(ipath='rxes', ival=deque(), iown=True),
connection=odict(ipath='connection', ival=None, iown=True),
address=odict(ipath='address', ival=odict(host='', port=7530, ha=None)),
txlog=odict(ipath='txlog', ival=odict(), iown=True),
rxlog=odict(ipath='rxlog', ival=odict(), iown=True), )
def postinitio(self, connection, address, **kwa):
""" Set up server to transmit and recive on address """
connection.value = aiding.SocketNB(host=address.data.host, port=address.data.port)
connection.value.reopen() # create socket connection
host, port = connection.value.ha
address.update(host=host, port=port, ha=(host, port))
return None
def action(self, txes, rxes, connection, address, txlog, rxlog, **kwa):
""" Receive any udp packets on server socket and put in rxes
Send any packets in txes
"""
server = connection.value
txl = txlog.value
rxl = rxlog.value
if server:
rxds = rxes.value
while (True):
rx, ra = server.receive() #if no data the tuple is ('',None)
if not rx: # no received data so break
break
rxds.append((rx, ra, address.data.ha))
rxl[ra] = rx
txds = txes.value
while txds:
tx, ta = txds.popleft()
server.send(tx, ta)
txl[ta] = tx
return None
class CloserServerRaet(deeding.ParamDeed):
""" CloserServerRaet closes server socket connection
inherited attributes
.name is actor name string
.store is data store ref
.ioinits is dict of io init data for initio
._parametric is flag for initio to not create attributes
"""
Ioinits = odict(
connection=odict(ipath='connection', ival=None))
def action(self, connection, **kwa):
""" Receive any udp packets on server socket and put in rxes
Send any packets in txes
"""
if connection.value:
connection.value.close()
return None
def Test():
"""Module Common self test
"""
pass
if __name__ == "__main__":
Test()

View File

@ -0,0 +1,458 @@
""" raeting module provides constants and values for the RAET protocol
Python Data format.
The data from which a packet is created is a nested dict of dicts.
What fields are included in a header is dependent on the meta data and the
header kind, service kind, packet kind and defaults as well as the neck body and tail.
Header encoding.
When the head kind is json = 0,then certain optimizations are
used to minimize the header length.
The header field keys are two bytes long
If a header field value is the default then the field is not included
Lengths are encoded as hex strings
The flags are encoded as a double char hex string in field 'fg'
data =
{
meta: dict of meta data about packet
{
sh: source host ip address (ipv4) Default: ''
sp: source ip port Default: 7532
dh: destination host ip address (ipv4) Default: '127.0.0.1'
dp: destination host ip port Default 7532
hk: header kind (HeadKind) Default 0
hl: header length (HeadLen) Default 0
nk: Neck header kind (NeckKind) Default '00' hs
nl: Neck header length (NeckLen) Default 0
bk: body kind (BodyKind) Default 0
bl: body length (BodyLen) Default 0
tk: tail kind (TailKind) Default 0
tl: tail length (TailLen) Default 0
}
head: dict of header fields
{
hk: header kind (HeadKind) Default 0
hl: header length (HeadLen) Default 0
vn: version (Version) Default 0
sd: Source Device ID (SDID)
dd: Destination Device ID (DDID)
cf: Corresponder Flag (CrdrFlag) Default 0
mf: Multicast Flag (MultFlag) Default 0
si: Session ID (SID) Default 0
ti: Transaction ID (TID) Default 0
sk: Service Kind (SrvcKind)
pk: Packet Kind (PcktKind)
bf: Burst Flag (BrstFlag) Default 0
Send segments or ordered packets without waiting for interleaved acks
oi: order index (OrdrIndx) Default 0
dt: Datetime Stamp (Datetime) Default 0
sn: Segment Number (SegNum) Default 0
sc: Segment Count (SegCnt) Default 1
pf: Pending Segment Flag (PendFlag) Default 0
Not the last segment more pending
af: All Flag (AllFlag) Default 0
Resend all segments not just one
nk: Neck header kind (NeckKind) Default '00' hs
nl: Neck header length (NeckLen) Default 0
bk: body kind (BodyKind) Default '00' hs
bl: body length (BodyLen) Default 0
tk: tail kind (TailKind) Default '00' hs
tl: tail length (TailLen) Default 0
fg: flags packed (Flags) Default '00' hs
2 byte Hex string with bits (0, 0, af, pf, 0, bf, mf, cf)
Zeros are TBD flags
pack: packed version of header
}
neck: dict of authentication fields
{
pack: packed version of neck
}
body: dict of body fields
{
pack: packed version of body
}
tail: dict of tail fields
{
pack: packed version of tail
}
pack: packed version of whole packet on tx and raw packet on rx
}
"""
import struct
from collections import namedtuple, Mapping
try:
import simplejson as json
except ImportError:
import json
from ioflo.base.odicting import odict
from ioflo.base.aiding import SocketNB
MAX_HEAD_LEN = 255
JSON_END = '\r\n\r\n'
DATA_PARTS = ['meta', 'head', 'neck', 'body', 'tail']
HEAD_KINDS = odict([('json', 0), ('binary', 1), ('unknown', 255)])
HEAD_KIND_NAMES = odict((v,k) for k, v in HEAD_KINDS.iteritems()) # inverse map
HeadKind = namedtuple('HeadKind', HEAD_KINDS.keys())
headKinds = HeadKind(**HEAD_KINDS) # headKinds.json is '00'
VERSIONS = odict([('0.1', 0)])
VERSION_NAMES = odict((v,k) for k, v in VERSIONS.iteritems())
NECK_KINDS = odict([('nada', 0), ('sodium', 1), ('sha2', 2),
('crc64', 2), ('unknown', 255)])
NECK_KIND_NAMES = odict((v,k) for k, v in NECK_KINDS.iteritems()) # inverse map
NeckKind = namedtuple('NeckKind', NECK_KINDS.keys())
neckKinds = NeckKind(**NECK_KINDS)
# bytes
NECK_SIZES = odict([('nada', 0), ('sodium', 0), ('sha2', 0),
('crc64', 8), ('unknown', 0)])
NeckSize = namedtuple('NeckSize', NECK_SIZES.keys())
neckSizes= NeckSize(**NECK_SIZES)
BODY_KINDS = odict([('nada', 0), ('json', 1), ('binary', 1), ('unknown', 255)])
BODY_KIND_NAMES = odict((v,k) for k, v in BODY_KINDS.iteritems()) # inverse map
BodyKind = namedtuple('BodyKind', BODY_KINDS.keys())
bodyKinds = BodyKind(**BODY_KINDS)
TAIL_KINDS = odict([('nada', 0), ('crc16', 1), ('crc64', 2),('unknown', 255)])
TAIL_KIND_NAMES = odict((v,k) for k, v in TAIL_KINDS.iteritems()) # inverse map
TailKind = namedtuple('TailKind', TAIL_KINDS.keys())
tailKinds = TailKind(**TAIL_KINDS)
# bytes
TAIL_SIZES = odict([('nada', 0), ('crc16', 2), ('crc64', 8),('unknown', 0)])
TailSize = namedtuple('TailSize', TAIL_SIZES.keys())
tailSizes= TailSize(**TAIL_SIZES)
SERVICE_KINDS = odict([('fireforget', 0), ('ackretry', 1), (
'unknown', 255)])
SERVICE_KIND_NAMES = odict((v,k) for k, v in SERVICE_KINDS.iteritems()) # inverse map
ServiceKind = namedtuple('ServiceKind', SERVICE_KINDS.keys())
serviceKinds = ServiceKind(**SERVICE_KINDS)
PACKET_KINDS = odict([('data', 0), ('req', 1), ('ack', 8),
('nack', 9), ('unknown', 255)])
PACKET_KIND_NAMES = odict((v,k) for k, v in PACKET_KINDS.iteritems()) # inverse map
PacketKind = namedtuple('PacketKind', PACKET_KINDS.keys())
packetKinds = PacketKind(**PACKET_KINDS)
# default values of meta data, if given, lengths are integers
META_DEFAULTS = odict( [
('sh', ''),
('sp', 7530),
('dh', '127.0.0.1'),
('dp', 7530),
('vn', 0),
('hk', None),
('hl', None),
('nk', 0),
('nl', 0),
('bk', 0),
('bl', 0),
('tk', 0),
('tl', 0),
])
# head fields that may be included in json header if not default value
HEAD_DEFAULTS = odict( [
('hk', None),
('hl', None),
('vn', 0),
('sd', None),
('dd', None),
('cf', 0),
('mf', 0),
('si', 0),
('ti', 0),
('sk', None),
('pk', None),
('bf', 0),
('oi', 0),
('dt', 0),
('sn', 0),
('sc', 1),
('pf', 0),
('af', 0),
('nk', 0),
('nl', 0),
('bk', 0),
('bl', 0),
('tk', 0),
('tl', 0),
])
META_LEN_FIELDS = ['nl', 'bl', 'tl'] # note 'hl' is special so not here
META_KIND_FIELDS = ['nk', 'bk', 'tk'] # note 'hk' is special so not here
def defaultData(data=None):
""" Returns defaulted data"""
if data is None:
data = odict()
for part in DATA_PARTS: # make sure all parts in data
if part not in data:
data[part] = odict()
if 'pack' not in data:
data['pack'] = ''
return data
def updateMissing(kit, defaults):
""" Update kit dict with item from default if item missing in kit"""
for k, v in defaults.items():
if k not in kit:
kit[k] = v
def packPacket(data):
""" Uses data to create packed version and assigns to pack field in data
Also returns packed packet
"""
meta = data['meta']
head = data['head']
neck = data['neck']
body = data['body']
tail = data['tail']
packBody(meta, body)
packTail(meta, body, tail)
packHead(meta, head)
packNeck(meta, head, neck)
data['pack'] = '{0}{1}{2}{3}'.format(head['pack'], neck['pack'], body['pack'], tail['pack'])
return (data['pack'])
def packBody(meta, body):
""" Uses meta, and body data to create packed version updates fields in body"""
body['pack'] = ''
if meta.get('bk') == bodyKinds.json:
kit = body.get('raw', '') or body.get('data', {})
packed = json.dumps(kit, separators=(',', ':'))
body['pack'] = packed
meta['bl'] = len(body['pack'])
def packTail(meta, body, tail):
""" Uses meta, and body data to create packed version of tail and updates meta and tail"""
tail['pack'] = ''
if meta.get('tk') == tailKinds.nada:
pass
meta['tl'] = len(tail['pack'])
def packHead(meta, head):
""" Uses meta and head data to create packed version and assigns to pack field in head"""
meta['error'] = ''
head['pack'] = ''
if head.get('hk') == headKinds.json:
kit = odict()
for field in META_LEN_FIELDS:
head[field] = meta[field]
for field in META_KIND_FIELDS:
head[field] = meta[field]
for k, v in HEAD_DEFAULTS.items():
if v is None:
kit[k] = head[k]
else:
if head[k] != v:
kit[k] = head[k]
kit['hl'] = '00' #need hex string so fixed length and jsonable
packed = json.dumps(kit, separators=(',', ':'), encoding='ascii',)
packed = "{0}{1}".format(packed, JSON_END)
hl = len(packed)
if hl > MAX_HEAD_LEN:
meta['error'] = "Head length of {0}, exceeds max of {1}".format(hl, MAX_HEAD_LEN)
meta['hl'] = 0
return
meta['hl'] = head['hl'] = hl
#subsitute true length converted to 2 byte hex string
packed = packed.replace('"hl":"00"', '"hl":"{0}"'.format("{0:02x}".format(hl)[-2:]), 1)
head['pack'] = packed
def packNeck(meta, head, neck):
""" Signs the head and puts auth signature into neck"""
neck['pack'] = ''
if meta.get('nk') == neckKinds.nada:
pass
meta['nl'] = len(neck['pack'])
def parsePacket(data):
""" Parses raw packet data in data['pack'] and updates data
"""
meta = data['meta']
head = data['head']
neck = data['neck']
body = data['body']
tail = data['tail']
pack = data['pack']
updateMissing(meta, META_DEFAULTS)
meta['error'] = ''
rest = parseHead(pack, meta, head)
rest = parseNeck(rest, meta, neck)
if not vouchHead(meta, head, neck):
return
rest = parseBody(rest, meta, body)
rest = parseTail(rest, meta, tail)
if not verifyBody(meta, head, tail):
return
return rest
def parseHead(pack, meta, head):
""" Parses and removes head from pack and returns remainder
updates meta and head dicts:"""
meta['error'] = ''
#need to test for Header type and version
if pack.startswith('{"hk":0,') and JSON_END in pack: #json header
meta['hk'] = headKinds.json
front, sep, back = pack.partition(JSON_END)
pack = back
head['pack'] = "{0}{1}".format(front, sep)
meta['hl'] = len(head['pack'])
head.update(HEAD_DEFAULTS)
kit = json.loads( front,
encoding='ascii',
object_pairs_hook=odict)
head.update(kit)
hl = int(head['hl'], 16)
if hl != meta['hl']:
meta['error'] = 'Actual head length does not match head field value.'
if head['hk'] != meta['hk']:
meta['error'] = 'Actual head kind does not match head field value.'
for field in META_LEN_FIELDS:
meta[field] = head[field]
for field in META_KIND_FIELDS:
meta[field] = head[field]
else: #notify unrecognizible packet
meta['hl'] = 0
meta['hk'] = headKinds.unknown
meta['error'] = "Unrecognizible packet head."
return pack
def parseNeck(pack, meta, neck):
""" Parses and removes neck from pack and returns remainder
updates meta and neck dicts.
"""
meta['error'] = ''
nl = meta.get('nl', 0)
neck['pack'] = pack[:nl]
pack = pack[nl:]
if meta.get('nk') == neckKinds.nada:
pass
else: #notify unrecognizible packet
meta['nl'] = 0
meta['nk'] = neckKinds.unknown
meta['error'] = "Unrecognizible packet neck."
return pack
def parseBody(pack, meta, body):
""" Parses and removes head from pack and returns remainder
updates meta and body dicts:"""
meta['error'] = ''
body['raw']= ''
bl = meta.get('bl', 0)
body['pack'] = pack[:bl]
pack = pack[bl:]
if meta.get('bk') == bodyKinds.json:
if bl:
kit = json.loads(body['pack'], object_pairs_hook=odict)
if isinstance(kit, Mapping):
body['data'] = kit
else:
body['raw'] = kit
else: #notify unrecognizible packet
meta['bl'] = 0
meta['bk'] = bodyKinds.unknown
meta['error'] = "Unrecognizible packet body."
return pack
def parseTail(pack, meta, tail):
""" Parses and removes tail from pack and returns remainder
updates meta and tail dicts.
"""
meta['error'] = ''
tl = meta.get('tl', 0)
tail['pack'] = pack[:tl]
pack = pack[tl:]
if meta.get('tk') == tailKinds.nada:
pass
else: #notify unrecognizible packet
meta['tl'] = 0
meta['tk'] = tailKinds.unknown
meta['error'] = "Unrecognizible packet tail."
return pack
def vouchHead(meta, head, neck):
""" Uses signature in neck to vouch for (authenticate) head
"""
#meta['error'] = "Head failed authentication."
return True
def verifyBody(meta, body, tail):
""" Uses tail to verify body does not have errors
"""
#meta['error'] = "Body failed verification."
return True
def sendPacket(data):
""" Uses data to create packed version and assigns to pack field in data
Also returns packed packet
"""
meta = data['meta']
head = data['head']
neck = data['neck']
body = data['body']
tail = data['tail']
packBody(meta, body)
packTail(meta, body, tail)
packHead(meta, head)
packNeck(meta, head, neck)
data['pack'] = '{0}{1}{2}{3}'.format(head['pack'], neck['pack'], body['pack'], tail['pack'])
return (data['pack'])

View File

@ -0,0 +1,18 @@
""" packeting.py raet protocol stacking behaviors
"""
#print "module %s" % __name__
from collections import deque
from ioflo.base.odicting import odict
from ioflo.base.globaling import *
from ioflo.base import aiding
from ioflo.base import storing
from ioflo.base import deeding
from ioflo.base.consoling import getConsole
console = getConsole()