VCL_IP
vmod_ip(const struct vrt_ctx *ctx, VCL_STRING s, VCL_IP d)
{
	struct addrinfo hints, *res0 = NULL;
	const struct addrinfo *res;
	int error;
	char *p;

	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
	AN(d);
	assert(VSA_Sane(d));

	if (s != NULL) {
		memset(&hints, 0, sizeof(hints));
		hints.ai_family = PF_UNSPEC;
		hints.ai_socktype = SOCK_STREAM;
		error = getaddrinfo(s, "80", &hints, &res0);
		if (!error) {
			for (res = res0; res != NULL; res = res->ai_next) {
				if (VSA_Sane(res->ai_addr) &&
				    res->ai_addrlen >= VSA_Len(res->ai_addr)) {
					d = res->ai_addr;
					break;
				}
			}
		}
	}
	AN(d);
	p = WS_Alloc(ctx->ws, VSA_Len(d));
	AN(p);
	memcpy(p, d, VSA_Len(d));
	if (res0 != NULL)
		freeaddrinfo(res0);
	return (p);
}
Beispiel #2
0
int
VTCP_connect(const struct suckaddr *name, int msec)
{
	int s, i;
	struct pollfd fds[1];
	const struct sockaddr *sa;
	socklen_t sl;
	int val;

	if (name == NULL)
		return (-1);
	/* Attempt the connect */
	AN(VSA_Sane(name));
	sa = VSA_Get_Sockaddr(name, &sl);
	AN(sa);
	AN(sl);

	s = socket(sa->sa_family, SOCK_STREAM, 0);
	if (s < 0)
		return (s);

	/* Set the socket non-blocking */
	if (msec != 0)
		(void)VTCP_nonblocking(s);

	val = 1;
	AZ(setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &val, sizeof val));

	i = connect(s, sa, sl);
	if (i == 0)
		return (s);
	if (errno != EINPROGRESS) {
		AZ(close(s));
		return (-1);
	}

	if (msec < 0) {
		/*
		 * Caller is responsible for waiting and
		 * calling VTCP_connected
		 */
		return (s);
	}

	assert(msec > 0);
	/* Exercise our patience, polling for write */
	fds[0].fd = s;
	fds[0].events = POLLWRNORM;
	fds[0].revents = 0;
	i = poll(fds, 1, msec);

	if (i == 0) {
		/* Timeout, close and give up */
		AZ(close(s));
		errno = ETIMEDOUT;
		return (-1);
	}

	return (VTCP_connected(s));
}
static void
ses_vsl_socket(struct sess *sp, const char *lsockname)
{
	struct sockaddr_storage ss;
	socklen_t sl;
	char laddr[ADDR_BUFSIZE];
	char lport[PORT_BUFSIZE];

	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
	AN(lsockname);

	AN(sp->addrs);
	sl = sizeof ss;
	AZ(getsockname(sp->fd, (void*)&ss, &sl));
	AN(VSA_Build(sess_local_addr(sp), &ss, sl));
	assert(VSA_Sane(sess_local_addr(sp)));

	VTCP_name(sess_remote_addr(sp), laddr, sizeof laddr,
	    lport, sizeof lport);
	sp->client_addr_str = WS_Copy(sp->ws, laddr, -1);
	sp->client_port_str = WS_Copy(sp->ws, lport, -1);
	VTCP_name(sess_local_addr(sp), laddr, sizeof laddr,
	    lport, sizeof lport);
	VSL(SLT_Begin, sp->vxid, "sess 0 HTTP/1");
	VSL(SLT_SessOpen, sp->vxid, "%s %s %s %s %s %.6f %d",
	    sp->client_addr_str, sp->client_port_str, lsockname, laddr, lport,
	    sp->t_open, sp->fd);
}
Beispiel #4
0
int
VRT_acl_match(VRT_CTX, VCL_ACL acl, VCL_IP ip)
{

	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
	CHECK_OBJ_NOTNULL(acl, VRT_ACL_MAGIC);
	assert(VSA_Sane(ip));
	return (acl->match(ctx, ip));
}
Beispiel #5
0
VCL_BOOL
vmod_match_acl(VRT_CTX, VCL_ACL acl, VCL_IP ip)
{

	CHECK_OBJ_ORNULL(ctx, VRT_CTX_MAGIC);
	CHECK_OBJ_ORNULL(acl, VRT_ACL_MAGIC);
	assert(VSA_Sane(ip));

	return (VRT_acl_match(ctx, acl, ip));
}
Beispiel #6
0
struct suckaddr *
VSA_Clone(const struct suckaddr *sua)
{
	struct suckaddr *sua2;

	assert(VSA_Sane(sua));
	sua2 = calloc(1, vsa_suckaddr_len);
	XXXAN(sua2);
	memcpy(sua2, sua, vsa_suckaddr_len);
	return (sua2);
}
Beispiel #7
0
int
VSA_Compare_IP(const struct suckaddr *sua1, const struct suckaddr *sua2)
{

	assert(VSA_Sane(sua1));
	assert(VSA_Sane(sua2));

	if (sua1->sa_family != sua2->sa_family)
		return (-1);

	switch (sua1->sa_family) {
	case PF_INET:
		return (memcmp(&sua1->sa.sa4.sin_addr,
		    &sua2->sa.sa4.sin_addr, sizeof(struct in_addr)));
	case PF_INET6:
		return (memcmp(&sua1->sa.sa6.sin6_addr,
		    &sua2->sa.sa6.sin6_addr, sizeof(struct in6_addr)));
	case PF_UNIX:
		return (strcmp(sua1->sa.sau->sun_path, sua2->sa.sau->sun_path));
	default:
		WRONG("Just plain insane");
	}
	NEEDLESS(return(-1));
}
Beispiel #8
0
int
VTCP_connect(int s, const struct suckaddr *name, int msec)
{
	int i, k;
	socklen_t l;
	struct pollfd fds[1];
	const struct sockaddr *sa;
	socklen_t sl;

	assert(s >= 0);

	/* Set the socket non-blocking */
	if (msec > 0)
		(void)VTCP_nonblocking(s);

	/* Attempt the connect */
	AN(VSA_Sane(name));
	sa = VSA_Get_Sockaddr(name, &sl);
	i = connect(s, sa, sl);
	if (i == 0 || errno != EINPROGRESS)
		return (i);

	assert(msec > 0);
	/* Exercise our patience, polling for write */
	fds[0].fd = s;
	fds[0].events = POLLWRNORM;
	fds[0].revents = 0;
	i = poll(fds, 1, msec);

	if (i == 0) {
		/* Timeout, close and give up */
		errno = ETIMEDOUT;
		return (-1);
	}

	/* Find out if we got a connection */
	l = sizeof k;
	AZ(getsockopt(s, SOL_SOCKET, SO_ERROR, &k, &l));

	/* An error means no connection established */
	errno = k;
	if (k)
		return (-1);

	(void)VTCP_blocking(s);
	return (0);
}
Beispiel #9
0
struct suckaddr *
VSA_Clone(const struct suckaddr *sua)
{
	struct suckaddr *sua2;
	struct sockaddr_un *suds;

	assert(VSA_Sane(sua));
	sua2 = calloc(1, vsa_suckaddr_len);
	XXXAN(sua2);
	memcpy(sua2, sua, vsa_suckaddr_len);
	if (sua->sa_family == PF_UNIX && sua->sa.sau != NULL) {
		suds = calloc(1, sizeof(struct sockaddr_un));
		XXXAN(suds);
		memcpy(suds, sua->sa.sau, sizeof(struct sockaddr_un));
		sua2->sa.sau = suds;
	}
	return (sua2);
}
VCL_IP
vmod_ip(VRT_CTX, VCL_STRING s, VCL_IP d)
{
	struct addrinfo hints, *res0 = NULL;
	const struct addrinfo *res;
	int error;
	void *p;
	struct suckaddr *r;

	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
	AN(d);
	assert(VSA_Sane(d));

	p = WS_Alloc(ctx->ws, vsa_suckaddr_len);
	if (p == NULL) {
		VSLb(ctx->vsl, SLT_VCL_Error,
		    "vmod std.ip(): insufficient workspace");
		return d;
	}
	r = NULL;

	if (s != NULL) {
		memset(&hints, 0, sizeof(hints));
		hints.ai_family = PF_UNSPEC;
		hints.ai_socktype = SOCK_STREAM;
		error = getaddrinfo(s, "80", &hints, &res0);
		if (!error) {
			for (res = res0; res != NULL; res = res->ai_next) {
				r = VSA_Build(p, res->ai_addr, res->ai_addrlen);
				if (r != NULL)
					break;
			}
		}
	}
	if (r == NULL) {
		r = p;
		memcpy(r, d, vsa_suckaddr_len);
	}
	if (res0 != NULL)
		freeaddrinfo(res0);
	return (r);
}