diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5733bf82..ab6edc6c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,7 +12,8 @@ set(machine_src mm_loop.c mm_tls.c mm_io.c mm_close.c - mm_connect.c) # mm_tls_io.c mm_dns.c mm_bind.c mm_accept.c mm_read.c mm_write.c) + mm_connect.c + mm_bind.c) # mm_accept.c mm_read.c mm_write.c mm_dns.c mm_tls_io.c) add_library(machine_library_shared SHARED ${machine_src}) set_target_properties(machine_library_shared PROPERTIES OUTPUT_NAME ${machine_library}) diff --git a/src/mm_bind.c b/src/mm_bind.c index f41d6894..43baba27 100644 --- a/src/mm_bind.c +++ b/src/mm_bind.c @@ -13,11 +13,30 @@ machine_bind(machine_io_t obj, struct sockaddr *sa) { mm_io_t *io = obj; mm_io_set_errno(io, 0); - int rc; - rc = uv_tcp_bind(&io->handle, sa, 0); - if (rc < 0) { - mm_io_set_errno_uv(io, rc); + if (io->connected) { + mm_io_set_errno(io, EINPROGRESS); return -1; } + int rc; + rc = mm_io_socket(io, sa); + if (rc == -1) + goto error; + rc = mm_socket_set_reuseaddr(io->fd, 1); + if (rc == -1) { + mm_io_set_errno(io, errno); + goto error; + } + rc = mm_socket_bind(io->fd, sa); + if (rc == -1) { + mm_io_set_errno(io, errno); + goto error; + } return 0; +error: + if (io->fd != -1) { + close(io->fd); + io->fd = -1; + } + io->handle.fd = -1; + return -1; } diff --git a/src/mm_connect.c b/src/mm_connect.c index 1ccf601f..6477ce71 100644 --- a/src/mm_connect.c +++ b/src/mm_connect.c @@ -38,46 +38,6 @@ mm_connect_cb(mm_fd_t *handle, int mask) return 0; } -static int -mm_connect_socket(mm_io_t *io, struct sockaddr *sa) -{ - int rc; - rc = mm_socket(sa->sa_family, SOCK_STREAM, 0); - if (rc == -1) { - mm_io_set_errno(io, errno); - return -1; - } - io->fd = rc; - rc = mm_socket_set_nosigpipe(io->fd, 1); - if (rc == -1) { - mm_io_set_errno(io, errno); - return -1; - } - rc = mm_socket_set_nonblock(io->fd, 1); - if (rc == -1) { - mm_io_set_errno(io, errno); - return -1; - } - if (io->opt_nodelay) { - rc = mm_socket_set_nodelay(io->fd, 1); - if (rc == -1) { - mm_io_set_errno(io, errno); - return -1; - } - } - if (io->opt_keepalive) { - rc = mm_socket_set_keepalive(io->fd, 1, io->opt_keepalive_delay); - if (rc == -1) { - mm_io_set_errno(io, errno); - return -1; - } - } - io->handle.fd = io->fd; - io->handle.callback = NULL; - io->handle.arg = io; - return 0; -} - static int mm_connect(mm_io_t *io, struct sockaddr *sa, uint64_t time_ms) { @@ -103,7 +63,7 @@ mm_connect(mm_io_t *io, struct sockaddr *sa, uint64_t time_ms) /* create socket */ int rc; - rc = mm_connect_socket(io, sa); + rc = mm_io_socket(io, sa); if (rc == -1) goto error; diff --git a/src/mm_io.c b/src/mm_io.c index 8569f7a6..9ab0d9c2 100644 --- a/src/mm_io.c +++ b/src/mm_io.c @@ -153,3 +153,42 @@ machine_set_readahead(machine_io_t obj, int size) */ return 0; } + +int mm_io_socket(mm_io_t *io, struct sockaddr *sa) +{ + int rc; + rc = mm_socket(sa->sa_family, SOCK_STREAM, 0); + if (rc == -1) { + mm_io_set_errno(io, errno); + return -1; + } + io->fd = rc; + rc = mm_socket_set_nosigpipe(io->fd, 1); + if (rc == -1) { + mm_io_set_errno(io, errno); + return -1; + } + rc = mm_socket_set_nonblock(io->fd, 1); + if (rc == -1) { + mm_io_set_errno(io, errno); + return -1; + } + if (io->opt_nodelay) { + rc = mm_socket_set_nodelay(io->fd, 1); + if (rc == -1) { + mm_io_set_errno(io, errno); + return -1; + } + } + if (io->opt_keepalive) { + rc = mm_socket_set_keepalive(io->fd, 1, io->opt_keepalive_delay); + if (rc == -1) { + mm_io_set_errno(io, errno); + return -1; + } + } + io->handle.fd = io->fd; + io->handle.callback = NULL; + io->handle.arg = io; + return 0; +} diff --git a/src/mm_io.h b/src/mm_io.h index ece12a96..9b102965 100644 --- a/src/mm_io.h +++ b/src/mm_io.h @@ -91,4 +91,6 @@ mm_io_set_errno(mm_io_t *io, int rc) io->errno_ = rc; } +int mm_io_socket(mm_io_t*, struct sockaddr*); + #endif diff --git a/src/mm_socket.c b/src/mm_socket.c index 42c7983f..a6e74c8f 100644 --- a/src/mm_socket.c +++ b/src/mm_socket.c @@ -75,6 +75,16 @@ int mm_socket_set_nosigpipe(int fd, int enable) return 0; } +int mm_socket_set_reuseaddr(int fd, int enable) +{ + int rc; + rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &enable, + sizeof(enable)); + if (rc == -1) + return -1; + return 0; +} + int mm_socket_error(int fd) { int error; @@ -105,3 +115,22 @@ int mm_socket_connect(int fd, struct sockaddr *sa) return -1; return 0; } + +int mm_socket_bind(int fd, struct sockaddr *sa) +{ + int addrlen; + if (sa->sa_family == AF_INET) { + addrlen = sizeof(struct sockaddr_in); + } else + if (sa->sa_family == AF_INET6) { + addrlen = sizeof(struct sockaddr_in6); + } else { + errno = EINVAL; + return -1; + } + int rc; + rc = bind(fd, sa, addrlen); + if (rc == -1) + return -1; + return 0; +} diff --git a/src/mm_socket.h b/src/mm_socket.h index bbb7cbdc..8a8d1033 100644 --- a/src/mm_socket.h +++ b/src/mm_socket.h @@ -12,7 +12,9 @@ int mm_socket_set_nonblock(int, int); int mm_socket_set_nodelay(int, int); int mm_socket_set_keepalive(int, int, int); int mm_socket_set_nosigpipe(int, int); +int mm_socket_set_reuseaddr(int, int); int mm_socket_error(int); int mm_socket_connect(int, struct sockaddr*); +int mm_socket_bind(int, struct sockaddr*); #endif