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))); }
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; }