Browse Source

Add universal utility function for creating stream sockets.

tags/0.4.5
Vsevolod Stakhov 12 years ago
parent
commit
89c8b90f8e
5 changed files with 102 additions and 5 deletions
  1. 1
    1
      src/lmtp_proto.c
  2. 1
    1
      src/main.c
  3. 1
    1
      src/smtp_utils.c
  4. 87
    1
      src/util.c
  5. 12
    1
      src/util.h

+ 1
- 1
src/lmtp_proto.c View File

@@ -452,7 +452,7 @@ lmtp_deliver_mta (struct worker_task *task)

if (task->cfg->deliver_family == AF_UNIX) {
un = alloca (sizeof (struct sockaddr_un));
sock = make_unix_socket (task->cfg->deliver_host, un, FALSE);
sock = make_unix_socket (task->cfg->deliver_host, un, FALSE, TRUE);
}
else {
sock = make_tcp_socket (&task->cfg->deliver_addr, task->cfg->deliver_port, FALSE, TRUE);

+ 1
- 1
src/main.c View File

@@ -473,7 +473,7 @@ create_listen_socket (struct in_addr *addr, gint port, gint family, gchar *path)
}
else {
un_addr = (struct sockaddr_un *)alloca (sizeof (struct sockaddr_un));
if (!un_addr || (listen_sock = make_unix_socket (path, un_addr, TRUE)) == -1) {
if (!un_addr || (listen_sock = make_unix_socket (path, un_addr, TRUE, TRUE)) == -1) {
msg_err ("cannot create unix listen socket. %s", strerror (errno));
}
}

+ 1
- 1
src/smtp_utils.c View File

@@ -78,7 +78,7 @@ create_smtp_upstream_connection (struct smtp_session *session)
/* Now try to create socket */
if (selected->is_unix) {
un = alloca (sizeof (struct sockaddr_un));
session->upstream_sock = make_unix_socket (selected->name, un, FALSE);
session->upstream_sock = make_unix_socket (selected->name, un, FALSE, TRUE);
}
else {
session->upstream_sock = make_tcp_socket (&selected->addr, selected->port, FALSE, TRUE);

+ 87
- 1
src/util.c View File

@@ -215,7 +215,7 @@ accept_from_socket (gint listen_sock, struct sockaddr *addr, socklen_t * len)
}

gint
make_unix_socket (const gchar *path, struct sockaddr_un *addr, gboolean is_server)
make_unix_socket (const gchar *path, struct sockaddr_un *addr, gboolean is_server, gboolean async)
{
gint fd, s_error, r, optlen, serrno, on = 1;

@@ -258,6 +258,20 @@ make_unix_socket (const gchar *path, struct sockaddr_un *addr, gboolean is_serve
msg_warn ("bind/connect failed: %d, '%s'", errno, strerror (errno));
goto out;
}
if (!async) {
/* Try to poll */
if (poll_sync_socket (fd, CONNECT_TIMEOUT * 1000, POLLOUT) <= 0) {
errno = ETIMEDOUT;
msg_warn ("bind/connect failed: timeout");
goto out;
}
else {
/* Make synced again */
if (make_socket_blocking (fd) < 0) {
goto out;
}
}
}
}
else {
/* Still need to check SO_ERROR on socket */
@@ -279,6 +293,78 @@ make_unix_socket (const gchar *path, struct sockaddr_un *addr, gboolean is_serve
return (-1);
}

/**
* Make universal stream socket
* @param credits host, ip or path to unix socket
* @param port port (used for network sockets)
* @param async make this socket asynced
* @param is_server make this socket as server socket
* @param try_resolve try name resolution for a socket (BLOCKING)
*/
gint
make_universal_stream_socket (const gchar *credits, guint16 port, gboolean async, gboolean is_server, gboolean try_resolve)
{
struct sockaddr_un un;
struct stat st;
struct in_addr in;
struct hostent *he;
gint r;

if (*credits == '/') {
r = stat (credits, &st);
if (is_server) {
if (r == -1) {
return make_unix_socket (credits, &un, is_server, async);
}
else {
/* Unix socket exists, it must be unlinked first */
errno = EEXIST;
return -1;
}
}
else {
if (r == -1) {
/* Unix socket doesn't exists it must be created first */
errno = ENOENT;
return -1;
}
else {
if ((st.st_mode & S_IFSOCK) == 0) {
/* Path is not valid socket */
errno = EINVAL;
return -1;
}
else {
return make_unix_socket (credits, &un, is_server, async);
}
}
}
}
else {
/* TCP related part */
if (inet_aton (credits, &in) == 0) {
/* Try to resolve */
if (try_resolve) {
if ((he = gethostbyname (credits)) == NULL) {
errno = ENOENT;
return -1;
}
else {
memcpy (&in, he->h_addr, sizeof (struct in_addr));
return make_tcp_socket (&in, port, is_server, async);
}
}
else {
errno = ENOENT;
return -1;
}
}
else {
return make_tcp_socket (&in, port, is_server, async);
}
}
}

gint
make_socketpair (gint pair[2])
{

+ 12
- 1
src/util.h View File

@@ -44,7 +44,18 @@ gint accept_from_socket (gint listen_sock, struct sockaddr *addr, socklen_t *len
/*
* Create and bind or connect unix socket
*/
gint make_unix_socket (const gchar *, struct sockaddr_un *, gboolean is_server);
gint make_unix_socket (const gchar *, struct sockaddr_un *, gboolean is_server, gboolean async);

/**
* Make universal stream socket
* @param credits host, ip or path to unix socket
* @param port port (used for network sockets)
* @param async make this socket asynced
* @param is_server make this socket as server socket
* @param try_resolve try name resolution for a socket (BLOCKING)
*/
gint make_universal_stream_socket (const gchar *credits, guint16 port,
gboolean async, gboolean is_server, gboolean try_resolve);

/*
* Create socketpair

Loading…
Cancel
Save