static void vpx_enc_port(struct vsb *vsb, const struct suckaddr *s) { uint8_t b[2]; vbe16enc(b, (uint16_t)VSA_Port(s)); VSB_bcat(vsb, b, sizeof(b)); }
static void vep_emit_len(const struct vep_state *vep, ssize_t l, int m8, int m16, int m64) { uint8_t buf[9]; assert(l > 0); if (l < 256) { buf[0] = (uint8_t)m8; buf[1] = (uint8_t)l; assert((ssize_t)buf[1] == l); VSB_bcat(vep->vsb, buf, 2); } else if (l < 65536) { buf[0] = (uint8_t)m16; vbe16enc(buf + 1, (uint16_t)l); assert((ssize_t)vbe16dec(buf + 1) == l); VSB_bcat(vep->vsb, buf, 3); } else { buf[0] = (uint8_t)m64; vbe64enc(buf + 1, l); assert((ssize_t)vbe64dec(buf + 1) == l); VSB_bcat(vep->vsb, buf, 9); } }
int VRY_Match(struct req *req, const uint8_t *vary) { uint8_t *vsp = req->vary_b; char *h, *e; unsigned lh, ln; int i, oflo = 0; AN(vsp); while (vary[2]) { if (vsp + 2 >= req->vary_e) { /* * Too little workspace to find out */ oflo = 1; break; } i = vry_cmp(vary, vsp); if (i == 1) { /* * Different header, build a new entry, * then compare again with that new entry. */ ln = 2 + vary[2] + 2; i = http_GetHdr(req->http, (const char*)(vary+2), &h); if (i) { /* Trim trailing space */ e = strchr(h, '\0'); while (e > h && vct_issp(e[-1])) e--; lh = e - h; assert(lh < 0xffff); ln += lh; } else { e = h = NULL; lh = 0xffff; } if (vsp + ln + 2 >= req->vary_e) { /* * Not enough space to build new entry * and put terminator behind it. */ oflo = 1; break; } vbe16enc(vsp, (uint16_t)lh); memcpy(vsp + 2, vary + 2, vary[2] + 2); if (h != NULL) memcpy(vsp + 2 + vsp[2] + 2, h, lh); vsp[ln + 0] = 0xff; vsp[ln + 1] = 0xff; vsp[ln + 2] = 0; (void)VRY_Validate(vsp); req->vary_l = vsp + ln + 3; i = vry_cmp(vary, vsp); assert(i == 0 || i == 2); } if (i == 0) { /* Same header, same contents */ vsp += VRY_Len(vsp); vary += VRY_Len(vary); } else if (i == 2) { /* Same header, different contents, cannot match */ return (0); } } if (oflo) { vsp = req->vary_b; req->vary_l = NULL; if (vsp + 2 < req->vary_e) { vsp[0] = 0xff; vsp[1] = 0xff; vsp[2] = 0; } return (0); } else { return (1); } }
int VRY_Match(struct sess *sp, const uint8_t *vary) { uint8_t *vsp = sp->vary_b; char *h, *e; unsigned lh, ln; int i, retval = 1, oflo = 0; AN(vsp); while (vary[2]) { i = vry_cmp(&vary, &vsp); if (i == 1) { /* Build a new entry */ i = http_GetHdr(sp->http, (const char*)(vary+2), &h); if (i) { /* Trim trailing space */ e = strchr(h, '\0'); while (e > h && vct_issp(e[-1])) e--; lh = e - h; assert(lh < 0xffff); } else { e = h = NULL; lh = 0xffff; } /* Length of the entire new vary entry */ ln = 2 + vary[2] + 2 + (lh == 0xffff ? 0 : lh); if (vsp + ln >= sp->vary_e) { vsp = sp->vary_b; oflo = 1; } /* * We MUST have space for one entry and the end marker * after it, which prevents old junk from confusing us */ assert(vsp + ln + 2 < sp->vary_e); vbe16enc(vsp, (uint16_t)lh); memcpy(vsp + 2, vary + 2, vary[2] + 2); if (h != NULL && e != NULL) { memcpy(vsp + 2 + vsp[2] + 2, h, e - h); vsp[2 + vary[2] + 2 + (e - h) + 2] = '\0'; } else vsp[2 + vary[2] + 2 + 2] = '\0'; i = vry_cmp(&vary, &vsp); assert(i != 1); /* hdr must be the same now */ } if (i != 0) retval = 0; vsp += vry_len(vsp); vary += vry_len(vary); } if (vsp + 3 > sp->vary_e) oflo = 1; if (oflo) { /* XXX: Should log this */ vsp = sp->vary_b; } vsp[0] = 0xff; vsp[1] = 0xff; vsp[2] = 0; if (oflo) sp->vary_l = NULL; else sp->vary_l = vsp + 3; return (retval); }