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