예제 #1
0
vmod_set_ip_tos(VRT_CTX, VCL_INT tos)
{
	struct suckaddr *sa;
	int itos = tos;

	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
	AZ(SES_Get_local_addr(ctx->req->sp, &sa));
	/* Silently ignore for non-IP addresses. */
	if (VSA_Compare(sa, bogo_ip) == 0)
		return;
	VTCP_Assert(setsockopt(ctx->req->sp->fd,
	    IPPROTO_IP, IP_TOS, &itos, sizeof(itos)));
}
예제 #2
0
static void
vbp_poke(struct vbp_target *vt)
{
	int s, tmo, i, proxy_header, err;
	vtim_real t_start, t_now, t_end;
	unsigned rlen, resp;
	char buf[8192], *p;
	struct pollfd pfda[1], *pfd = pfda;
	const struct suckaddr *sa;

	t_start = t_now = VTIM_real();
	t_end = t_start + vt->timeout;

	s = VTP_Open(vt->tcp_pool, t_end - t_now, (const void **)&sa, &err);
	if (s < 0) {
		bprintf(vt->resp_buf, "Open error %d (%s)", err, strerror(err));
		Lck_Lock(&vbp_mtx);
		if (vt->backend)
			VBE_Connect_Error(vt->backend->vsc, err);
		Lck_Unlock(&vbp_mtx);
		return;
	}

	i = VSA_Get_Proto(sa);
	if (VSA_Compare(sa, bogo_ip) == 0)
		vt->good_unix |= 1;
	else if (i == AF_INET)
		vt->good_ipv4 |= 1;
	else if (i == AF_INET6)
		vt->good_ipv6 |= 1;
	else
		WRONG("Wrong probe protocol family");

	t_now = VTIM_real();
	tmo = (int)round((t_end - t_now) * 1e3);
	if (tmo <= 0) {
		bprintf(vt->resp_buf,
			"Open timeout %.3fs exceeded by %.3fs",
			vt->timeout, t_now - t_end);
		VTCP_close(&s);
		return;
	}

	Lck_Lock(&vbp_mtx);
	if (vt->backend != NULL)
		proxy_header = vt->backend->proxy_header;
	else
		proxy_header = -1;
	Lck_Unlock(&vbp_mtx);

	if (proxy_header < 0) {
		bprintf(vt->resp_buf, "%s", "No backend");
		VTCP_close(&s);
		return;
	}

	/* Send the PROXY header */
	assert(proxy_header <= 2);
	if (proxy_header == 1) {
		if (vbp_write_proxy_v1(vt, &s) != 0)
			return;
	} else if (proxy_header == 2 &&
	    vbp_write(vt, &s, vbp_proxy_local, sizeof vbp_proxy_local) != 0)
		return;

	/* Send the request */
	if (vbp_write(vt, &s, vt->req, vt->req_len) != 0)
		return;
	vt->good_xmit |= 1;

	pfd->fd = s;
	rlen = 0;
	while (1) {
		pfd->events = POLLIN;
		pfd->revents = 0;
		tmo = (int)round((t_end - t_now) * 1e3);
		if (tmo > 0)
			i = poll(pfd, 1, tmo);
		if (i == 0) {
			vt->err_recv |= 1;
			bprintf(vt->resp_buf, "Poll error %d (%s)",
				errno, strerror(errno));
			VTCP_close(&s);
			return;
		}
		if (tmo <= 0) {
			bprintf(vt->resp_buf,
				"Poll (read) timeout %.3fs exceeded by %.3fs",
				vt->timeout, t_now - t_end);
			VTCP_close(&s);
			return;
		}
		if (rlen < sizeof vt->resp_buf)
			i = read(s, vt->resp_buf + rlen,
			    sizeof vt->resp_buf - rlen);
		else
			i = read(s, buf, sizeof buf);
		if (i <= 0) {
			if (i < 0)
				bprintf(vt->resp_buf, "Read error %d (%s)",
					errno, strerror(errno));
			break;
		}
		rlen += i;
	}

	VTCP_close(&s);

	if (i < 0) {
		/* errno reported above */
		vt->err_recv |= 1;
		return;
	}

	if (rlen == 0) {
		bprintf(vt->resp_buf, "%s", "Empty response");
		return;
	}

	/* So we have a good receive ... */
	t_now = VTIM_real();
	vt->last = t_now - t_start;
	vt->good_recv |= 1;

	/* Now find out if we like the response */
	vt->resp_buf[sizeof vt->resp_buf - 1] = '\0';
	p = strchr(vt->resp_buf, '\r');
	if (p != NULL)
		*p = '\0';
	p = strchr(vt->resp_buf, '\n');
	if (p != NULL)
		*p = '\0';

	i = sscanf(vt->resp_buf, "HTTP/%*f %u ", &resp);

	if (i == 1 && resp == vt->exp_status)
		vt->happy |= 1;
}