Example #1
0
ret_t
cherokee_socket_gethostbyname (cherokee_socket_t *socket, cherokee_buffer_t *hostname)
{
#ifndef _WIN32
	ret_t                    ret;
	cherokee_resolv_cache_t *resolv = NULL;

	/* Unix sockets
	 */
	if (SOCKET_AF(socket) == AF_UNIX) {
		memset ((char*) SOCKET_SUN_PATH(socket), 0,
			sizeof (SOCKET_ADDR_UNIX(socket)));

		SOCKET_ADDR_UNIX(socket)->sun_family = AF_UNIX;

		if (hostname->buf[0] == '@') {
			strncpy (SOCKET_SUN_PATH (socket) + 1, hostname->buf + 1,
			         (sizeof (SOCKET_ADDR_UNIX(socket)->sun_path) - 1) - sizeof(short));
			SOCKET_SUN_PATH (socket)[0] = 0;
		}
		else {
			strncpy (SOCKET_SUN_PATH (socket), hostname->buf,
			         sizeof (SOCKET_ADDR_UNIX(socket)->sun_path) - sizeof(short));
		}

		return ret_ok;
	}

	/* TCP sockets
	 */
	ret = cherokee_resolv_cache_get_default (&resolv);
	if (ret != ret_ok) {
		return ret_error;
	}

	ret = cherokee_resolv_cache_get_host (resolv, hostname, socket);
	if (ret != ret_ok) {
		return ret_error;
	}

	return ret_ok;
#else
	SHOULDNT_HAPPEN;
	return ret_no_sys;
#endif
}
Example #2
0
static ret_t
cherokee_bind_local (cherokee_socket_t *sock, cherokee_buffer_t *listen_to)
{
#ifdef HAVE_SOCKADDR_UN
	int         re;
	struct stat buf;

	/* Sanity check
	 */
	if ((listen_to->len <= 0) ||
	    (listen_to->len >= sizeof(SOCKET_SUN_PATH(sock))))
		return ret_error;

	/* Remove the socket if it already exists
	 */
	re = cherokee_stat (listen_to->buf, &buf);
	if (re == 0) {
		if (! S_ISSOCK(buf.st_mode)) {
			LOG_CRITICAL (CHEROKEE_ERROR_SOCKET_NO_SOCKET, listen_to->buf);
			return ret_error;
		}

		re = cherokee_unlink (listen_to->buf);
		if (re != 0) {
			LOG_ERRNO (errno, cherokee_err_error,
				   CHEROKEE_ERROR_SOCKET_REMOVE, listen_to->buf);
			return ret_error;
		}
	}

	/* Create the socket
	 */
	memcpy (SOCKET_SUN_PATH(sock), listen_to->buf, listen_to->len + 1);
	sock->client_addr_len = sizeof(SOCKET_ADDR_UNIX(sock)->sun_family) + listen_to->len;

	re = bind (SOCKET_FD(sock),
	           (const struct sockaddr *)SOCKET_ADDR_UNIX(sock),
	           sock->client_addr_len);
	if (re != 0) return ret_error;

	return ret_ok;
#else
	return ret_no_sys;
#endif
}
Example #3
0
ret_t
cherokee_socket_gethostbyname (cherokee_socket_t *socket, cherokee_buffer_t *hostname)
{
	if (SOCKET_AF(socket) == AF_UNIX) {
#ifdef _WIN32
		SHOULDNT_HAPPEN;
		return ret_no_sys;
#else
		memset ((char*) SOCKET_SUN_PATH(socket), 0,
			sizeof (SOCKET_ADDR_UNIX(socket)));

		SOCKET_ADDR_UNIX(socket)->sun_family = AF_UNIX;

		strncpy (SOCKET_SUN_PATH (socket), hostname->buf,
			 sizeof (SOCKET_ADDR_UNIX(socket)->sun_path) - sizeof(short));

		return ret_ok;
#endif
	}

	return cherokee_gethostbyname (hostname->buf, &SOCKET_SIN_ADDR(socket));
}
Example #4
0
ret_t
cherokee_socket_connect (cherokee_socket_t *sock)
{
	int r;
	int err;

	TRACE (ENTRIES",connect", "connect type=%s\n",
	       SOCKET_AF(sock) == AF_INET  ? "AF_INET"  :
	       SOCKET_AF(sock) == AF_INET6 ? "AF_INET6" :
	       SOCKET_AF(sock) == AF_UNIX  ? "AF_UNIX"  : "Unknown");

	do {
		switch (SOCKET_AF(sock)) {
		case AF_INET:
			r = connect (SOCKET_FD(sock),
			             (struct sockaddr *) &SOCKET_ADDR(sock),
			             sizeof(struct sockaddr_in));
			break;
#ifdef HAVE_IPV6
		case AF_INET6:
			r = connect (SOCKET_FD(sock),
			             (struct sockaddr *) &SOCKET_ADDR(sock),
			             sizeof(struct sockaddr_in6));
			break;
#endif
#ifdef HAVE_SOCKADDR_UN
		case AF_UNIX:
			if (SOCKET_SUN_PATH (socket)[0] != 0) {
				r = connect (SOCKET_FD(sock),
				             (struct sockaddr *) &SOCKET_ADDR(sock),
				             SUN_LEN (SOCKET_ADDR_UNIX(sock)));
			}
			else {
				r = connect (SOCKET_FD(sock),
				             (struct sockaddr *) &SOCKET_ADDR(sock),
				             SUN_ABSTRACT_LEN (SOCKET_ADDR_UNIX(sock)));
			}
			break;
#endif
		default:
			SHOULDNT_HAPPEN;
			return ret_no_sys;
		}
	} while ((r == -1) && (errno == EINTR));

	if (r < 0) {
		err = SOCK_ERRNO();
		TRACE (ENTRIES",connect", "connect error=%d '%s'\n", err, strerror(err));

		switch (err) {
		case EISCONN:
			break;
		case EINVAL:
		case ENOENT:
		case ECONNRESET:
		case ECONNREFUSED:
		case EADDRNOTAVAIL:
			return ret_deny;
		case ETIMEDOUT:
			return ret_error;
		case EAGAIN:
		case EALREADY:
		case EINPROGRESS:
#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
		case EWOULDBLOCK:
#endif
			return ret_eagain;
		default:
			LOG_ERRNO_S (errno, cherokee_err_error, CHEROKEE_ERROR_SOCKET_CONNECT);
			return ret_error;
		}
	}

	TRACE (ENTRIES",connect", "succeed. fd=%d\n", SOCKET_FD(sock));

	sock->status = socket_reading;
	return ret_ok;
}