int pycbc_tc_simple_decode(PyObject **vp, const char *buf, size_t nbuf, lcb_uint32_t flags) { return decode_common(vp, buf, nbuf, flags); }
int pycbc_tc_decode_value(pycbc_Bucket *conn, const void *value, size_t nvalue, lcb_uint32_t flags, PyObject **pobj) { PyObject *result = NULL; PyObject *pint = NULL; PyObject *pbuf = NULL; int rv; if (conn->data_passthrough == 0 && conn->tc == NULL) { return decode_common(pobj, value, nvalue, flags); } if (conn->data_passthrough) { *pobj = PyBytes_FromStringAndSize(value, nvalue); if (*pobj) { return 0; } return -1; } pbuf = PyBytes_FromStringAndSize(value, nvalue); if (!pbuf) { pbuf = PyBytes_FromString(""); } pint = pycbc_IntFromUL(flags); if (!pint) { PYCBC_EXC_WRAP(PYCBC_EXC_INTERNAL, 0, "Couldn't create flags object"); rv = -1; goto GT_DONE; } rv = do_call_tc(conn, pbuf, pint, &result, DECODE_VALUE); GT_DONE: Py_XDECREF(pint); Py_XDECREF(pbuf); if (rv < 0) { return -1; } *pobj = result; return 0; }
int pycbc_tc_decode_key(pycbc_Bucket *conn, const void *key, size_t nkey, PyObject **pobj) { PyObject *bobj; int rv = 0; if (conn->data_passthrough) { bobj = PyBytes_FromStringAndSize(key, nkey); *pobj = bobj; } else if (!conn->tc) { return decode_common(pobj, key, nkey, PYCBC_FMT_UTF8); } else { bobj = PyBytes_FromStringAndSize(key, nkey); if (bobj) { rv = do_call_tc(conn, bobj, NULL, pobj, DECODE_KEY); Py_XDECREF(bobj); } else { rv = -1; } if (rv < 0) { return -1; } } if (*pobj == NULL) { return -1; } if (PyObject_Hash(*pobj) == -1) { PYCBC_EXC_WRAP_KEY(PYCBC_EXC_ENCODING, 0, "Transcoder.decode_key must return a hashable object", *pobj); Py_XDECREF(*pobj); return -1; } return 0; }
byte * decode(dcontext_t *dcontext, byte *pc, instr_t *instr) { return decode_common(dcontext, pc, pc, instr); }
/** Examine a datagram and determine what to do with it. * */ static int process_udp( n2n_sn_t * sss, const struct sockaddr_in * sender_sock, const uint8_t * udp_buf, size_t udp_size, time_t now) { n2n_common_t cmn; /* common fields in the packet header */ size_t rem; size_t idx; size_t msg_type; uint8_t from_supernode; macstr_t mac_buf; macstr_t mac_buf2; n2n_sock_str_t sockbuf; traceEvent( TRACE_DEBUG, "process_udp(%lu)", udp_size ); /* Use decode_common() to determine the kind of packet then process it: * * REGISTER_SUPER adds an edge and generate a return REGISTER_SUPER_ACK * * REGISTER, REGISTER_ACK and PACKET messages are forwarded to their * destination edge. If the destination is not known then PACKETs are * broadcast. */ rem = udp_size; /* Counts down bytes of packet to protect against buffer overruns. */ idx = 0; /* marches through packet header as parts are decoded. */ if ( decode_common(&cmn, udp_buf, &rem, &idx) < 0 ) { traceEvent( TRACE_ERROR, "Failed to decode common section" ); return -1; /* failed to decode packet */ } msg_type = cmn.pc; /* packet code */ from_supernode= cmn.flags & N2N_FLAGS_FROM_SUPERNODE; if ( cmn.ttl < 1 ) { traceEvent( TRACE_WARNING, "Expired TTL" ); return 0; /* Don't process further */ } --(cmn.ttl); /* The value copied into all forwarded packets. */ if ( msg_type == MSG_TYPE_PACKET ) { /* PACKET from one edge to another edge via supernode. */ /* pkt will be modified in place and recoded to an output of potentially * different size due to addition of the socket.*/ n2n_PACKET_t pkt; n2n_common_t cmn2; uint8_t encbuf[N2N_SN_PKTBUF_SIZE]; size_t encx=0; int unicast; /* non-zero if unicast */ const uint8_t * rec_buf; /* either udp_buf or encbuf */ sss->stats.last_fwd=now; decode_PACKET( &pkt, &cmn, udp_buf, &rem, &idx ); unicast = (0 == is_multi_broadcast(pkt.dstMac) ); traceEvent( TRACE_DEBUG, "Rx PACKET (%s) %s -> %s %s", (unicast?"unicast":"multicast"), macaddr_str( mac_buf, pkt.srcMac ), macaddr_str( mac_buf2, pkt.dstMac ), (from_supernode?"from sn":"local") ); if ( !from_supernode ) { memcpy( &cmn2, &cmn, sizeof( n2n_common_t ) ); /* We are going to add socket even if it was not there before */ cmn2.flags |= N2N_FLAGS_SOCKET | N2N_FLAGS_FROM_SUPERNODE; pkt.sock.family = AF_INET; pkt.sock.port = ntohs(sender_sock->sin_port); memcpy( pkt.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE ); rec_buf = encbuf; /* Re-encode the header. */ encode_PACKET( encbuf, &encx, &cmn2, &pkt ); /* Copy the original payload unchanged */ encode_buf( encbuf, &encx, (udp_buf + idx), (udp_size - idx ) ); } else { /* Already from a supernode. Nothing to modify, just pass to * destination. */ traceEvent( TRACE_DEBUG, "Rx PACKET fwd unmodified" ); rec_buf = udp_buf; encx = udp_size; } /* Common section to forward the final product. */ if ( unicast ) { try_forward( sss, &cmn, pkt.dstMac, rec_buf, encx ); } else { try_broadcast( sss, &cmn, pkt.srcMac, rec_buf, encx ); } }/* MSG_TYPE_PACKET */ else if ( msg_type == MSG_TYPE_REGISTER ) { /* Forwarding a REGISTER from one edge to the next */ n2n_REGISTER_t reg; n2n_common_t cmn2; uint8_t encbuf[N2N_SN_PKTBUF_SIZE]; size_t encx=0; int unicast; /* non-zero if unicast */ const uint8_t * rec_buf; /* either udp_buf or encbuf */ sss->stats.last_fwd=now; decode_REGISTER( ®, &cmn, udp_buf, &rem, &idx ); unicast = (0 == is_multi_broadcast(reg.dstMac) ); if ( unicast ) { traceEvent( TRACE_DEBUG, "Rx REGISTER %s -> %s %s", macaddr_str( mac_buf, reg.srcMac ), macaddr_str( mac_buf2, reg.dstMac ), ((cmn.flags & N2N_FLAGS_FROM_SUPERNODE)?"from sn":"local") ); if ( 0 != (cmn.flags & N2N_FLAGS_FROM_SUPERNODE) ) { memcpy( &cmn2, &cmn, sizeof( n2n_common_t ) ); /* We are going to add socket even if it was not there before */ cmn2.flags |= N2N_FLAGS_SOCKET | N2N_FLAGS_FROM_SUPERNODE; reg.sock.family = AF_INET; reg.sock.port = ntohs(sender_sock->sin_port); memcpy( reg.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE ); rec_buf = encbuf; /* Re-encode the header. */ encode_REGISTER( encbuf, &encx, &cmn2, ® ); /* Copy the original payload unchanged */ encode_buf( encbuf, &encx, (udp_buf + idx), (udp_size - idx ) ); } else { /* Already from a supernode. Nothing to modify, just pass to * destination. */ rec_buf = udp_buf; encx = udp_size; } try_forward( sss, &cmn, reg.dstMac, rec_buf, encx ); /* unicast only */ } else { traceEvent( TRACE_ERROR, "Rx REGISTER with multicast destination" ); } } else if ( msg_type == MSG_TYPE_REGISTER_ACK ) { traceEvent( TRACE_DEBUG, "Rx REGISTER_ACK (NOT IMPLEMENTED) SHould not be via supernode" ); } else if ( msg_type == MSG_TYPE_REGISTER_SUPER ) { n2n_REGISTER_SUPER_t reg; n2n_REGISTER_SUPER_ACK_t ack; n2n_common_t cmn2; uint8_t ackbuf[N2N_SN_PKTBUF_SIZE]; size_t encx=0; /* Edge requesting registration with us. */ sss->stats.last_reg_super=now; ++(sss->stats.reg_super); decode_REGISTER_SUPER( ®, &cmn, udp_buf, &rem, &idx ); cmn2.ttl = N2N_DEFAULT_TTL; cmn2.pc = n2n_register_super_ack; cmn2.flags = N2N_FLAGS_SOCKET | N2N_FLAGS_FROM_SUPERNODE; memcpy( cmn2.community, cmn.community, sizeof(n2n_community_t) ); memcpy( &(ack.cookie), &(reg.cookie), sizeof(n2n_cookie_t) ); memcpy( ack.edgeMac, reg.edgeMac, sizeof(n2n_mac_t) ); ack.lifetime = reg_lifetime( sss ); ack.sock.family = AF_INET; ack.sock.port = ntohs(sender_sock->sin_port); memcpy( ack.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE ); ack.num_sn=0; /* No backup */ memset( &(ack.sn_bak), 0, sizeof(n2n_sock_t) ); traceEvent( TRACE_DEBUG, "Rx REGISTER_SUPER for %s [%s]", macaddr_str( mac_buf, reg.edgeMac ), sock_to_cstr( sockbuf, &(ack.sock) ) ); update_edge( sss, reg.edgeMac, cmn.community, &(ack.sock), now ); #ifdef N2N_MULTIPLE_SUPERNODES { struct comm_info *ci = comm_find(sss->communities.list_head, cmn.community, strlen((const char *) cmn.community)); if (ci) { ack.num_sn = ci->sn_num; memcpy(&ack.sn_bak, ci->sn_sock, ci->sn_num * sizeof(n2n_sock_t)); } } #endif encode_REGISTER_SUPER_ACK( ackbuf, &encx, &cmn2, &ack ); sendto( sss->sock, ackbuf, encx, 0, (struct sockaddr *)sender_sock, sizeof(struct sockaddr_in) ); traceEvent( TRACE_DEBUG, "Tx REGISTER_SUPER_ACK for %s [%s]", macaddr_str( mac_buf, reg.edgeMac ), sock_to_cstr( sockbuf, &(ack.sock) ) ); } return 0; }