static VALUE unixsock_connect_internal(VALUE a) { struct unixsock_arg *arg = (struct unixsock_arg *)a; return (VALUE)rsock_connect(arg->fd, (struct sockaddr*)arg->sockaddr, (socklen_t)sizeof(*arg->sockaddr), 0); }
static VALUE unixsock_connect_internal(VALUE a) { struct unixsock_arg *arg = (struct unixsock_arg *)a; return (VALUE)rsock_connect(arg->fd, (struct sockaddr*)arg->sockaddr, arg->sockaddrlen, 0); }
static VALUE udp_connect_internal(struct udp_arg *arg) { int fd = arg->fd; struct addrinfo *res; for (res = arg->res; res; res = res->ai_next) { if (rsock_connect(fd, res->ai_addr, res->ai_addrlen, 0) >= 0) { return Qtrue; } } return Qfalse; }
static VALUE unixsock_connect_internal(struct unixsock_arg *arg) { return (VALUE)rsock_connect(arg->fd, (struct sockaddr*)arg->sockaddr, sizeof(*arg->sockaddr), 0); }
static VALUE init_inetsock_internal(struct inetsock_arg *arg) { int type = arg->type; struct addrinfo *res; int fd, status = 0; const char *syscall = 0; arg->remote.res = rsock_addrinfo(arg->remote.host, arg->remote.serv, SOCK_STREAM, (type == INET_SERVER) ? AI_PASSIVE : 0); /* * Maybe also accept a local address */ if (type != INET_SERVER && (!NIL_P(arg->local.host) || !NIL_P(arg->local.serv))) { arg->local.res = rsock_addrinfo(arg->local.host, arg->local.serv, SOCK_STREAM, 0); } arg->fd = fd = -1; for (res = arg->remote.res; res; res = res->ai_next) { #if !defined(INET6) && defined(AF_INET6) if (res->ai_family == AF_INET6) continue; #endif status = rsock_socket(res->ai_family,res->ai_socktype,res->ai_protocol); syscall = "socket(2)"; fd = status; if (fd < 0) { continue; } arg->fd = fd; if (type == INET_SERVER) { #if !defined(_WIN32) && !defined(__CYGWIN__) status = 1; setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&status, (socklen_t)sizeof(status)); #endif status = bind(fd, res->ai_addr, res->ai_addrlen); syscall = "bind(2)"; } else { if (arg->local.res) { status = bind(fd, arg->local.res->ai_addr, arg->local.res->ai_addrlen); syscall = "bind(2)"; } if (status >= 0) { status = rsock_connect(fd, res->ai_addr, res->ai_addrlen, (type == INET_SOCKS)); syscall = "connect(2)"; } } if (status < 0) { close(fd); arg->fd = fd = -1; continue; } else break; } if (status < 0) { rb_sys_fail(syscall); } arg->fd = -1; if (type == INET_SERVER) { status = listen(fd, SOMAXCONN); if (status < 0) { close(fd); rb_sys_fail("listen(2)"); } } /* create new instance */ return rsock_init_sock(arg->sock, fd); }
static VALUE init_inetsock_internal(struct inetsock_arg *arg) { int error = 0; int type = arg->type; struct addrinfo *res, *lres; int fd, status = 0, local = 0; const char *syscall = 0; arg->remote.res = rsock_addrinfo(arg->remote.host, arg->remote.serv, SOCK_STREAM, (type == INET_SERVER) ? AI_PASSIVE : 0); /* * Maybe also accept a local address */ if (type != INET_SERVER && (!NIL_P(arg->local.host) || !NIL_P(arg->local.serv))) { arg->local.res = rsock_addrinfo(arg->local.host, arg->local.serv, SOCK_STREAM, 0); } arg->fd = fd = -1; for (res = arg->remote.res->ai; res; res = res->ai_next) { #if !defined(INET6) && defined(AF_INET6) if (res->ai_family == AF_INET6) continue; #endif lres = NULL; if (arg->local.res) { for (lres = arg->local.res->ai; lres; lres = lres->ai_next) { if (lres->ai_family == res->ai_family) break; } if (!lres) { if (res->ai_next || status < 0) continue; /* Use a different family local address if no choice, this * will cause EAFNOSUPPORT. */ lres = arg->local.res->ai; } } status = rsock_socket(res->ai_family,res->ai_socktype,res->ai_protocol); syscall = "socket(2)"; fd = status; if (fd < 0) { error = errno; continue; } arg->fd = fd; if (type == INET_SERVER) { #if !defined(_WIN32) && !defined(__CYGWIN__) status = 1; setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&status, (socklen_t)sizeof(status)); #endif status = bind(fd, res->ai_addr, res->ai_addrlen); syscall = "bind(2)"; } else { if (lres) { status = bind(fd, lres->ai_addr, lres->ai_addrlen); local = status; syscall = "bind(2)"; } if (status >= 0) { status = rsock_connect(fd, res->ai_addr, res->ai_addrlen, (type == INET_SOCKS)); syscall = "connect(2)"; } } if (status < 0) { error = errno; close(fd); arg->fd = fd = -1; continue; } else break; } if (status < 0) { VALUE host, port; if (local < 0) { host = arg->local.host; port = arg->local.serv; } else { host = arg->remote.host; port = arg->remote.serv; } rsock_syserr_fail_host_port(error, syscall, host, port); } arg->fd = -1; if (type == INET_SERVER) { status = listen(fd, SOMAXCONN); if (status < 0) { error = errno; close(fd); rb_syserr_fail(error, "listen(2)"); } } /* create new instance */ return rsock_init_sock(arg->sock, fd); }