/usr/lib/python2.7/dist-packages/ccnet/packet.py is in libccnet0 6.1.5-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | #coding: UTF-8
"""
Packet level protocol of ccnet.
About various types of id:
- A slave processor's id has its highest bit set; a master processor has its highest bit clear
- The <id> field of a ccnet packet always has its highest bit clear. The
<type> field of the packet determines what type of the packet is (a
request, a response, or an update)
"""
import logging
import struct
from ccnet.utils import recvall, sendall, NetworkError
REQUEST_ID_MASK = 0x7fffffff
SLAVE_BIT_MASK = 0x80000000
CCNET_MSG_OK = 0
CCNET_MSG_HANDSHAKE = 1
CCNET_MSG_REQUEST = 2
CCNET_MSG_RESPONSE = 3
CCNET_MSG_UPDATE = 4
CCNET_MSG_RELAY = 5
def to_request_id(id):
return id & REQUEST_ID_MASK
to_response_id = to_request_id
to_update_id = to_request_id
to_master_id = to_request_id
to_packet_id = to_request_id
def to_slave_id(id):
return id | SLAVE_BIT_MASK
def to_print_id(id):
if id & SLAVE_BIT_MASK:
return -to_request_id(id)
else:
return id
# the byte sequence of ccnet packet header
CCNET_HEADER_FORMAT = '>BBHI'
# Number of bytes for the header
CCNET_HEADER_LENGTH = struct.calcsize(CCNET_HEADER_FORMAT)
CCNET_MAX_PACKET_LENGTH = 65535
class PacketHeader(object):
def __init__(self, ver, ptype, length, id):
self.ver = ver
self.ptype = ptype
self.length = length
self.id = id
def to_string(self):
return struct.pack(CCNET_HEADER_FORMAT, self.ver, self.ptype, self.length, self.id)
def __str__(self):
return "<PacketHeader: type = %d, length = %d, id = %u>" % (self.ptype, self.length, self.id)
class Packet(object):
version = 1
def __init__(self, header, body):
self.header = header
self.body = body
def parse_header(buf):
try:
ver, ptype, length, id = struct.unpack(CCNET_HEADER_FORMAT, buf)
except struct.error, e:
raise NetworkError('error when unpack packet header: %s' % e)
return PacketHeader(ver, ptype, length, id)
def format_response(code, code_msg, content):
body = code
if code_msg:
body += " " + code_msg
body += "\n"
if content:
body += content
return body
format_update = format_response
def request_to_packet(id, buf):
hdr = PacketHeader(1, CCNET_MSG_REQUEST, len(buf), to_request_id(id))
return Packet(hdr, buf)
def response_to_packet(id, code, code_msg, content):
body = format_response(code, code_msg, content)
hdr = PacketHeader(1, CCNET_MSG_RESPONSE, len(body), to_response_id(id))
return Packet(hdr, body)
def update_to_packet(id, code, code_msg, content):
body = format_update(code, code_msg, content)
hdr = PacketHeader(1, CCNET_MSG_UPDATE, len(body), to_update_id(id))
return Packet(hdr, body)
def read_packet(fd):
hdr = recvall(fd, CCNET_HEADER_LENGTH)
if len(hdr) == 0:
logging.warning('connection to daemon is lost')
raise NetworkError('Connection to daemon is lost')
elif len(hdr) < CCNET_HEADER_LENGTH:
raise NetworkError('Only read %d bytes header, expected 8' % len(hdr))
header = parse_header(hdr)
if header.length == 0:
body = ''
else:
body = recvall(fd, header.length)
if len(body) < header.length:
raise NetworkError('Only read %d bytes body, expected %d' % (len(body), header.length))
return Packet(header, body)
def write_packet(fd, packet):
hdr = packet.header.to_string()
sendall(fd, hdr)
sendall(fd, packet.body)
|