示例#1
0
/* If an explicit source binding is specified on the server and/or backend, and
 * this source makes use of the transparent proxy, then it is extracted now and
 * assigned to the session's pending connection. This function assumes that an
 * outgoing connection has already been assigned to s->si[1].end.
 */
static void assign_tproxy_address(struct session *s)
{
#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_TRANSPARENT)
	struct server *srv = objt_server(s->target);
	struct conn_src *src;
	struct connection *cli_conn;
	struct connection *srv_conn = objt_conn(s->si[1].end);

	if (srv && srv->conn_src.opts & CO_SRC_BIND)
		src = &srv->conn_src;
	else if (s->be->conn_src.opts & CO_SRC_BIND)
		src = &s->be->conn_src;
	else
		return;

	switch (src->opts & CO_SRC_TPROXY_MASK) {
	case CO_SRC_TPROXY_ADDR:
		srv_conn->addr.from = src->tproxy_addr;
		break;
	case CO_SRC_TPROXY_CLI:
	case CO_SRC_TPROXY_CIP:
		/* FIXME: what can we do if the client connects in IPv6 or unix socket ? */
		cli_conn = objt_conn(s->si[0].end);
		if (cli_conn)
			srv_conn->addr.from = cli_conn->addr.from;
		else
			memset(&srv_conn->addr.from, 0, sizeof(srv_conn->addr.from));
		break;
	case CO_SRC_TPROXY_DYN:
		if (src->bind_hdr_occ) {
			char *vptr;
			int vlen;
			int rewind;

			/* bind to the IP in a header */
			((struct sockaddr_in *)&srv_conn->addr.from)->sin_family = AF_INET;
			((struct sockaddr_in *)&srv_conn->addr.from)->sin_port = 0;
			((struct sockaddr_in *)&srv_conn->addr.from)->sin_addr.s_addr = 0;

			b_rew(s->req.buf, rewind = http_hdr_rewind(&s->txn.req));
			if (http_get_hdr(&s->txn.req, src->bind_hdr_name, src->bind_hdr_len,
					 &s->txn.hdr_idx, src->bind_hdr_occ, NULL, &vptr, &vlen)) {
				((struct sockaddr_in *)&srv_conn->addr.from)->sin_addr.s_addr =
					htonl(inetaddr_host_lim(vptr, vptr + vlen));
			}
			b_adv(s->req.buf, rewind);
		}
		break;
	default:
		memset(&srv_conn->addr.from, 0, sizeof(srv_conn->addr.from));
	}
#endif
}
示例#2
0
/*
 * Add data to compress
 */
int http_compression_buffer_add_data(struct session *s, struct buffer *in, struct buffer *out)
{
	struct http_msg *msg = &s->txn.rsp;
	int consumed_data = 0;
	int data_process_len;
	int block1, block2;

	/*
	 * Temporarily skip already parsed data and chunks to jump to the
	 * actual data block. It is fixed before leaving.
	 */
	b_adv(in, msg->next);

	/*
	 * select the smallest size between the announced chunk size, the input
	 * data, and the available output buffer size. The compressors are
	 * assumed to be able to process all the bytes we pass to them at once.
	 */
	data_process_len = MIN(in->i, msg->chunk_len);
	data_process_len = MIN(out->size - buffer_len(out), data_process_len);

	block1 = data_process_len;
	if (block1 > bi_contig_data(in))
		block1 = bi_contig_data(in);
	block2 = data_process_len - block1;

	/* compressors return < 0 upon error or the amount of bytes read */
	consumed_data = s->comp_algo->add_data(s->comp_ctx, bi_ptr(in), block1, out);
	if (consumed_data >= 0 && block2 > 0) {
		consumed_data = s->comp_algo->add_data(s->comp_ctx, in->data, block2, out);
		if (consumed_data >= 0)
			consumed_data += block1;
	}

	/* restore original buffer pointer */
	b_rew(in, msg->next);

	if (consumed_data > 0) {
		msg->next += consumed_data;
		msg->chunk_len -= consumed_data;
	}
	return consumed_data;
}
示例#3
0
/* RDP Cookie HASH.  */
struct server *get_server_rch(struct session *s)
{
	unsigned int hash = 0;
	struct proxy    *px   = s->be;
	unsigned long    len;
	int              ret;
	struct sample    smp;
	int rewind;

	/* tot_weight appears to mean srv_count */
	if (px->lbprm.tot_weight == 0)
		return NULL;

	memset(&smp, 0, sizeof(smp));

	b_rew(s->req.buf, rewind = s->req.buf->o);

	ret = fetch_rdp_cookie_name(s, &smp, px->hh_name, px->hh_len);
	len = smp.data.str.len;

	b_adv(s->req.buf, rewind);

	if (ret == 0 || (smp.flags & SMP_F_MAY_CHANGE) || len == 0)
		return NULL;

	/* note: we won't hash if there's only one server left */
	if (px->lbprm.tot_used == 1)
		goto hash_done;

	/* Found a the hh_name in the headers.
	 * we will compute the hash based on this value ctx.val.
	 */
	hash = gen_hash(px, smp.data.str.str, len);

	if ((px->lbprm.algo & BE_LB_HASH_MOD) == BE_LB_HMOD_AVAL)
		hash = full_hash(hash);
 hash_done:
	if (px->lbprm.algo & BE_LB_LKUP_CHTREE)
		return chash_get_server_hash(px, hash);
	else
		return map_get_server_hash(px, hash);
}