static bytea * decrypt_internal(int is_pubenc, int need_text, text *data, text *key, text *keypsw, text *args) { int err; MBuf *src = NULL, *dst = NULL; uint8 tmp[VARHDRSZ]; uint8 *restmp; bytea *res; int res_len; PGP_Context *ctx = NULL; struct debug_expect ex; int got_unicode = 0; init_work(&ctx, need_text, args, &ex); src = mbuf_create_from_data((uint8 *) VARDATA(data), VARSIZE(data) - VARHDRSZ); dst = mbuf_create(VARSIZE(data) + 2048); /* * reserve room for header */ mbuf_append(dst, tmp, VARHDRSZ); /* * set key */ if (is_pubenc) { uint8 *psw = NULL; int psw_len = 0; MBuf *kbuf; if (keypsw) { psw = (uint8 *) VARDATA(keypsw); psw_len = VARSIZE(keypsw) - VARHDRSZ; } kbuf = create_mbuf_from_vardata(key); err = pgp_set_pubkey(ctx, kbuf, psw, psw_len, 1); mbuf_free(kbuf); } else err = pgp_set_symkey(ctx, (uint8 *) VARDATA(key), VARSIZE(key) - VARHDRSZ); /* * decrypt */ if (err >= 0) err = pgp_decrypt(ctx, src, dst); /* * failed? */ if (err < 0) goto out; if (ex.expect) check_expect(ctx, &ex); /* remember the setting */ got_unicode = pgp_get_unicode_mode(ctx); out: if (src) mbuf_free(src); if (ctx) pgp_free(ctx); if (err) { px_set_debug_handler(NULL); if (dst) mbuf_free(dst); ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), errmsg("%s", px_strerror(err)))); } res_len = mbuf_steal_data(dst, &restmp); mbuf_free(dst); /* res_len includes VARHDRSZ */ res = (bytea *) restmp; SET_VARSIZE(res, res_len); if (need_text && got_unicode) { text *utf = convert_from_utf8(res); if (utf != res) { clear_and_pfree(res); res = utf; } } px_set_debug_handler(NULL); /* * add successful decryptions also into RNG */ add_entropy(res, key, keypsw); return res; }
static bytea * encrypt_internal(int is_pubenc, int is_text, text *data, text *key, text *args) { MBuf *src, *dst; uint8 tmp[VARHDRSZ]; uint8 *restmp; bytea *res; int res_len; PGP_Context *ctx; int err; struct debug_expect ex; text *tmp_data = NULL; /* * Add data and key info RNG. */ add_entropy(data, key, NULL); init_work(&ctx, is_text, args, &ex); if (is_text && pgp_get_unicode_mode(ctx)) { tmp_data = convert_to_utf8(data); if (tmp_data == data) tmp_data = NULL; else data = tmp_data; } src = create_mbuf_from_vardata(data); dst = mbuf_create(VARSIZE(data) + 128); /* * reserve room for header */ mbuf_append(dst, tmp, VARHDRSZ); /* * set key */ if (is_pubenc) { MBuf *kbuf = create_mbuf_from_vardata(key); err = pgp_set_pubkey(ctx, kbuf, NULL, 0, 0); mbuf_free(kbuf); } else err = pgp_set_symkey(ctx, (uint8 *) VARDATA(key), VARSIZE(key) - VARHDRSZ); /* * encrypt */ if (err >= 0) err = pgp_encrypt(ctx, src, dst); /* * check for error */ if (err) { if (ex.debug) px_set_debug_handler(NULL); if (tmp_data) clear_and_pfree(tmp_data); pgp_free(ctx); mbuf_free(src); mbuf_free(dst); ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), errmsg("%s", px_strerror(err)))); } /* res_len includes VARHDRSZ */ res_len = mbuf_steal_data(dst, &restmp); res = (bytea *) restmp; SET_VARSIZE(res, res_len); if (tmp_data) clear_and_pfree(tmp_data); pgp_free(ctx); mbuf_free(src); mbuf_free(dst); px_set_debug_handler(NULL); return res; }
/* This will be called many time to advance rendering of an ubjson ctx */ static void ub_render_cont(struct ub_ctx *ctx) { struct mbuf *buf = &ctx->out, *stack = &ctx->stack; struct visit *cur; if (ctx->out.len > 0) { ub_call_cb(ctx, 0); } for (cur = cur_visit(stack); cur != NULL; cur = cur_visit(stack)) { ub_val_t obj = cur->obj; if (obj.kind == UBJSON_TYPE_NULL) { cs_ubjson_emit_null(buf); } else if (obj.kind == UBJSON_TYPE_TRUE) { cs_ubjson_emit_boolean(buf, 1); } else if (obj.kind == UBJSON_TYPE_FALSE) { cs_ubjson_emit_boolean(buf, 0); } else if (obj.kind == UBJSON_TYPE_NUMBER) { cs_ubjson_emit_autonumber(buf, obj.val.n); } else if (obj.kind == UBJSON_TYPE_STRING) { cs_ubjson_emit_string(buf, obj.val.s->s, strlen(obj.val.s->s)); } else if (obj.kind == UBJSON_TYPE_ARRAY) { unsigned long cur_idx = cur->v.next_idx; if (cur->v.next_idx == 0) { cs_ubjson_open_array(buf); } cur->v.next_idx++; if (cur->v.next_idx > ub_array_length(cur->obj)) { cs_ubjson_close_array(buf); } else { cur = push_visit(stack, ub_array_get(obj, cur_idx)); /* skip default popping of visitor frame */ continue; } } else if (obj.kind == UBJSON_TYPE_BIN) { ctx->bytes_left = obj.val.b->size; cs_ubjson_emit_bin_header(buf, ctx->bytes_left); pop_visit(stack); obj.val.b->cb(ctx, obj.val.b->user_data); /* * The user generator will reenter calling this function again with the * same context. */ return; } else if (obj.kind == UBJSON_TYPE_OBJECT) { const char *s; if (cur->v.p == NULL) { cs_ubjson_open_object(buf); } cur->v.p = ub_next_prop(obj, cur->v.p); if (cur->v.p == NULL) { cs_ubjson_close_object(buf); } else { s = cur->v.p->name->s; cs_ubjson_emit_object_key(buf, s, strlen(s)); cur = push_visit(stack, ub_get(obj, s)); /* skip default popping of visitor frame */ continue; } } else { printf("ubsjon: unsupported object: %d\n", obj.kind); } pop_visit(stack); } ub_call_cb(ctx, 1); mbuf_free(&ctx->out); ub_ctx_free(ctx); }
static void console_make_clubby_call_mbuf(struct v7 *v7, struct mbuf *logs) { mbuf_append(logs, "\0", 1); console_make_clubby_call(v7, logs->buf); mbuf_free(logs); }
UInt32 IOMbufMemoryCursor::genPhysicalSegments(mbuf_t packet, void *vector, UInt32 maxSegs, bool doCoalesce) { bool doneCoalesce = false; if (!packet || !(mbuf_flags(packet) & MBUF_PKTHDR)) return 0; if (!maxSegs) { maxSegs = maxNumSegments; if (!maxSegs) return 0; } if ( mbuf_next(packet) == 0 ) { uintptr_t src; struct IOPhysicalSegment physSeg; /* * the packet consists of only 1 mbuf * so if the data buffer doesn't span a page boundary * we can take the simple way out */ src = (uintptr_t)mbuf_data(packet); if ( trunc_page(src) == trunc_page(src + mbuf_len(packet) - 1) ) { physSeg.location = (IOPhysicalAddress) mbuf_data_to_physical((char *)src); if ( physSeg.location ) { physSeg.length = mbuf_len(packet); (*outSeg)(physSeg, vector, 0); return 1; } maxSegs = 1; if ( doCoalesce == false ) return 0; } } if ( doCoalesce == true && maxSegs == 1 ) { uintptr_t src; uintptr_t dst; mbuf_t m; mbuf_t mnext; mbuf_t out; UInt32 len = 0; struct IOPhysicalSegment physSeg; if ( mbuf_pkthdr_len(packet) > MCLBYTES ) return 0; m = packet; // Allocate a non-header mbuf + cluster. if (mbuf_getpacket( MBUF_DONTWAIT, &out )) return 0; mbuf_setflags( out, mbuf_flags( out ) & ~MBUF_PKTHDR ); dst = (uintptr_t)mbuf_data(out); do { src = (uintptr_t)mbuf_data(m); BCOPY( src, dst, mbuf_len(m) ); dst += mbuf_len(m); len += mbuf_len(m); } while ( (m = mbuf_next(m)) != 0 ); mbuf_setlen(out , len); dst = (uintptr_t)mbuf_data(out); physSeg.location = (IOPhysicalAddress) mbuf_data_to_physical((char *)dst); if (!physSeg.location) { mbuf_free(out); return 0; } physSeg.length = mbuf_len(out); (*outSeg)(physSeg, vector, 0); m = mbuf_next(packet); while (m != 0) { mnext = mbuf_next(m); mbuf_free(m); m = mnext; } // The initial header mbuf is preserved, its length set to zero, // and linked to the new packet chain. mbuf_setlen(packet , 0); mbuf_setnext(packet , out); mbuf_setnext(out , 0); return 1; } // // Iterate over the mbuf, translating segments were allowed. When we // are not allowed to translate segments then accumulate segment // statistics up to kMBufDataCacheSize of mbufs. Finally // if we overflow our cache just count how many segments this // packet represents. // UInt32 segsPerMBuf[kMBufDataCacheSize]; tryAgain: UInt32 curMBufIndex = 0; UInt32 curSegIndex = 0; UInt32 lastSegCount = 0; mbuf_t m = packet; // For each mbuf in incoming packet. do { vm_size_t mbufLen, thisLen = 0; uintptr_t src; // Step through each segment in the current mbuf for (mbufLen = mbuf_len(m), src = (uintptr_t)mbuf_data(m); mbufLen; src += thisLen, mbufLen -= thisLen) { // If maxSegmentSize is atleast PAGE_SIZE, then // thisLen = MIN(next_page(src), src + mbufLen) - src; thisLen = MIN(mbufLen, maxSegmentSize); thisLen = MIN(next_page(src), src + thisLen) - src; // If room left then find the current segment addr and output if (curSegIndex < maxSegs) { struct IOPhysicalSegment physSeg; physSeg.location = (IOPhysicalAddress) mbuf_data_to_physical((char *)src); if ( physSeg.location == 0 ) { return doCoalesce ? genPhysicalSegments(packet, vector, 1, true) : 0; } physSeg.length = thisLen; (*outSeg)(physSeg, vector, curSegIndex); } // Count segments if we are coalescing. curSegIndex++; } // Cache the segment count data if room is available. if (curMBufIndex < kMBufDataCacheSize) { segsPerMBuf[curMBufIndex] = curSegIndex - lastSegCount; lastSegCount = curSegIndex; } // Move on to next imcoming mbuf curMBufIndex++; m = mbuf_next(m); } while (m); // If we finished cleanly return number of segments found if (curSegIndex <= maxSegs) return curSegIndex; if (!doCoalesce) return 0; // if !coalescing we've got a problem. // If we are coalescing and it is possible then attempt coalesce, if (!doneCoalesce && (UInt) mbuf_pkthdr_len(packet) <= maxSegs * maxSegmentSize) { // Hmm, we have to do some coalescing. bool analysisRet; analysisRet = analyseSegments(packet, MIN(curMBufIndex, kMBufDataCacheSize), segsPerMBuf, curSegIndex, maxSegs); if (analysisRet) { doneCoalesce = true; coalesceCount++; goto tryAgain; } } assert(!doneCoalesce); // Problem in Coalesce code. packetTooBigErrors++; return 0; }
static inline void coalesceSegments(mbuf_t srcm, mbuf_t dstm) { uintptr_t src, dst; SInt32 srcLen, dstLen; mbuf_t temp; mbuf_t head = srcm; srcLen = (SInt32)mbuf_len( srcm ); src = (uintptr_t) mbuf_data(srcm); dstLen = (SInt32)mbuf_len( dstm ); dst = (uintptr_t) mbuf_data( dstm ); for (;;) { if (srcLen < dstLen) { // Copy remainder of src mbuf to current dst. BCOPY(src, dst, srcLen); dst += srcLen; dstLen -= srcLen; // Move on to the next source mbuf. temp = mbuf_next( srcm ); assert(temp); if(srcm != head) mbuf_free(srcm); srcm = temp; srcLen = (SInt32)mbuf_len( srcm ); src = (uintptr_t)mbuf_data(srcm); } else if (srcLen > dstLen) { // Copy some of src mbuf to remaining space in dst mbuf. BCOPY(src, dst, dstLen); src += dstLen; srcLen -= dstLen; // Move on to the next destination mbuf. temp = mbuf_next( dstm ); assert(temp); dstm = temp; dstLen = (SInt32)mbuf_len( dstm ); dst = (uintptr_t)mbuf_data( dstm ); } else { /* (srcLen == dstLen) */ // copy remainder of src into remaining space of current dst BCOPY(src, dst, srcLen); // Free current mbuf and move the current onto the next temp = mbuf_next( srcm ); if(srcm != head) mbuf_free(srcm); srcm = temp; // Do we have any more dest buffers to copy to? if (! mbuf_next ( dstm )) { // nope- hook the remainder of source chain to end of dest chain mbuf_setnext(dstm, srcm); break; } dstm = mbuf_next ( dstm ); assert(srcm); dstLen = (SInt32)mbuf_len ( dstm ); dst = (uintptr_t)mbuf_data( dstm ); srcLen = (SInt32)mbuf_len( srcm ); src = (uintptr_t)mbuf_data( srcm ); } } }