int sock_connect (const char *url, GError **err) { struct sockaddr_storage sas; gsize sas_len = sizeof(sas); if (!grid_string_to_sockaddr (url, (struct sockaddr*) &sas, &sas_len)) { g_error_transmit(err, NEWERROR(EINVAL, "invalid URL")); return -1; } int fd = socket_nonblock(sas.ss_family, SOCK_STREAM, 0); if (0 > fd) { g_error_transmit(err, NEWERROR(EINVAL, "socket error: (%d) %s", errno, strerror(errno))); return -1; } sock_set_reuseaddr(fd, TRUE); if (0 != metautils_syscall_connect (fd, (struct sockaddr*)&sas, sas_len)) { if (errno != EINPROGRESS && errno != 0) { g_error_transmit(err, NEWERROR(EINVAL, "connect error: (%d) %s", errno, strerror(errno))); metautils_pclose (&fd); return -1; } } sock_set_linger_default(fd); sock_set_nodelay(fd, TRUE); sock_set_tcpquickack(fd, TRUE); *err = NULL; return fd; }
static int sock_listen_open(void) { struct sockaddr_in srv; int sd = socket(AF_INET, SOCK_STREAM, 0); if(sd == -1) { error("sock_listen_open %s\n", strerror(errno)); abort(); } srv.sin_family = AF_INET; srv.sin_port = config->server.port; srv.sin_addr = config->server.inet4_addr; sock_set_reuseaddr(sd); if(-1 == bind(sd, (struct sockaddr *) &srv, sizeof(srv))) { error("sock_listen_open %s\n", strerror(errno)); abort(); } listen(sd, 1<<10); fd_open(sd, FD_SOCKET); return sd; }
int sock_server_create(struct sockaddr *addr) { int fd; int ret; fd = sock_create(); if(fd < 0) { return -1; } ret = sock_set_reuseaddr(fd); if(ret < 0) { goto err_server; } ret = sock_bind(fd, addr); if(ret < 0) { goto err_server; } ret = sock_listen(fd); if(ret < 0) { goto err_server; } return fd; err_server: sock_close(fd); return -1; }
gint accept_add_inet (ACCEPT_POOL ap, const gchar *h, const gchar *p, GError **err) { struct sockaddr_storage sa; gint srv = -1; if (!ap || !p) { GSETERROR (err, "Invalid parameter"); goto errorLabel; } if (!h || !(*h)) h = "0.0.0.0"; if (!resolve (&sa, h, p, err)) { GSETERROR(err,"Cannot resolve [%s]:%s", h, p); goto errorLabel; } /*create the server socket*/ if (-1 == (srv = socket (FAMILY(&sa), SOCK_STREAM, 0))) { GSETERROR(err,"Cannot open a %s socket (%s)", _get_family_name(FAMILY(&sa)), strerror(errno)); goto errorLabel; } if (!sock_set_reuseaddr(srv, TRUE)) { GSETERROR(err,"Cannot set SO_REUSEADDR on %d [%s]:%s (%s)", srv, h, p, strerror(errno)); goto errorLabel; } fcntl(srv, F_SETFL, O_NONBLOCK|fcntl(srv, F_GETFL)); if (-1 == bind (srv, (struct sockaddr*)(&sa), sizeof(struct sockaddr_in))) { GSETERROR(err,"Cannot bind %d on [%s]:%s (%s)", srv, h, p, strerror(errno)); goto errorLabel; } if (-1 == listen (srv,AP_BACKLOG)) { GSETERROR(err,"Cannot listen on %d [%s]:%s (%s)", srv, h, p, strerror(errno)); goto errorLabel; } if (!accept_add_any(ap,srv,err)) { GSETERROR(err,"Cannot monitor %s srv=%d", _get_family_name(FAMILY(&sa)), srv); goto errorLabel; } return 1; errorLabel: if (srv>=0) metautils_pclose(&srv); return 0; }
static int start_inet_server(GError **error) { struct sockaddr_in sin; worker_data_t wdata; DEBUG("Starting an INET server bond on 127.0.0.1:%d", inet_socket_port); memset(&wdata, 0x00, sizeof(wdata)); memset(&worker_inet, 0, sizeof(worker_t)); /* Create ressources to monitor */ sock_inet = socket_nonblock(PF_INET, SOCK_STREAM, 0); if (sock_inet < 0) { GSETERROR(error, "Failed to create socket : %s", strerror(errno)); return(0); } sock_set_reuseaddr(sock_inet, TRUE); /* Bind to file */ memset(&sin, 0x00, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(inet_socket_port); if (!inet_aton("127.0.0.1", &(sin.sin_addr))) { GSETERROR(error,"Invalid address : 127.0.0.1 !!!"); return 0; } if (-1 == bind(sock_inet, (struct sockaddr *)&sin, sizeof(sin))) { GSETERROR(error, "Failed to bind socket [%d] to address 127.0.0.1 : %s", sock_inet, strerror(errno)); return(0); } /* Listen on that socket */ if (-1 == listen(sock_inet, inet_socket_backlog)) { GSETERROR(error, "Failed to listen on socket [%d] : %s", sock_inet, strerror(errno)); return(0); } /* Create worker */ wdata.fd = sock_inet; wdata.sock_timeout = inet_socket_timeout; worker_inet.func = accept_worker; worker_inet.timeout.startup = 0; worker_inet.timeout.activity = 0; memcpy(&(worker_inet.data), &wdata, sizeof(worker_data_t)); /* Accept new connection */ if (!add_fd_to_io_scheduler(&worker_inet, EPOLLIN, error)) { GSETERROR(error,"Failed to add server sock to io_scheduler"); return 0; } INFO("INET server started on socket fd=%d 127.0.0.1:%d", sock_inet, inet_socket_port); return(1); }
static int tcpip_open(const gchar *h, const gchar *p) { GRID_DEBUG("opening tcp ip connection"); struct evutil_addrinfo ai_hint, *ai_res = NULL; int rc; socklen_t ss_len; struct sockaddr_storage ss; int fd; fd = socket(PF_INET, SOCK_STREAM, 0); if (fd < 0) { GRID_ERROR("accept error on fd=%d : %s", fd, strerror(errno)); return -1; } sock_set_linger_default(fd); sock_set_reuseaddr(fd, TRUE); bzero(&ai_hint, sizeof(ai_hint)); ai_hint.ai_flags = AI_NUMERICHOST; ai_hint.ai_family = PF_INET; ai_hint.ai_socktype = SOCK_STREAM; rc = evutil_getaddrinfo(h, p, &ai_hint, &ai_res); if (rc != 0) { errno = rc; return -1; } bzero(&ss, sizeof(ss)); ss_len = ai_res->ai_addrlen; g_memmove(&ss, (ai_res->ai_addr), ss_len); evutil_freeaddrinfo(ai_res); switch (connect(fd, (struct sockaddr *) &ss, ss_len)) { case 0: return fd; case -1: if (errno==EALREADY || errno==EAGAIN || errno==EINPROGRESS || errno==EWOULDBLOCK) { errno = 0; return fd; } return -1; default:/* unexpected */ return -1; } }
gint accept_add_local (ACCEPT_POOL ap, const gchar *l, GError **err) { struct working_parameter_s wrkParam; struct sockaddr_un sun; int srv = -1; if (!l || !(*l)) { GSETERROR(err,"invalid parameter"); goto errorLabel; } /*parse the URL*/ init_socket_options_defaults( l, &wrkParam ); parse_socket_options( &wrkParam ); /*try to stat the file*/ if (-1 == check_socket_is_absent( &wrkParam, err )) { GSETERROR(err,"A socket seems already present at [%s]", wrkParam.path.ptr); } /*open and bind the socket*/ if (-1==(srv=socket(PF_UNIX, SOCK_STREAM, 0))) { GSETERROR(err,"Cannot open a new socket PF_UNIX : %s", strerror(errno)); goto errorLabel; } if (!sock_set_reuseaddr(srv, TRUE)) { GSETERROR(err,"Cannot set SO_REUSEADDR on %d [%s] (%s)", srv, l, strerror(errno)); goto errorLabel; } fcntl(srv, F_SETFL, O_NONBLOCK|fcntl(srv, F_GETFL)); sun.sun_family = PF_LOCAL; strncpy(sun.sun_path, wrkParam.path.ptr, sizeof(sun.sun_path)); if (-1==bind (srv, (struct sockaddr*) &sun, sizeof(struct sockaddr_un))) { GSETERROR(err,"cannot bind srv=%d to %s (%s)", srv, l, strerror(errno)); goto errorLabel; } if (-1==listen (srv,AP_BACKLOG)) { GSETERROR(err,"cannot listen to inbound connections : %s", strerror(errno)); goto errorLabel; } if (!accept_add_any(ap,srv,err)) { GSETERROR(err,"Cannot monitor the local server"); goto errorLabel; } /*change socket rights*/ if (0 != chmod(wrkParam.path.ptr,wrkParam.mode)) { int errsav = errno; ERROR("Failed to set mode [%o] on UNIX socket [%s] : %s", wrkParam.mode, wrkParam.path.ptr, strerror(errsav)); SRV_SEND_WARNING("server","UNIX socket might be not accessible : failed to set mode [%o] on UNIX socket [%s] (%s)", wrkParam.mode, wrkParam.path.ptr, strerror(errsav)); } INFO("socket srv=%d %s now monitored", srv, _get_family_name(FAMILY(&sun))); return 1; errorLabel: if (srv>=0) metautils_pclose(&srv); return 0; }
static GError * _endpoint_open(struct endpoint_s *u) { EXTRA_ASSERT(u != NULL); struct sockaddr_storage ss; socklen_t ss_len = sizeof(ss); memset(&ss, 0, sizeof(ss)); /* patch some socket preferences that make sense only for INET sockets */ if (_endpoint_is_UNIX(u)) { u->port_real = 0; u->port_cfg = 0; u->flags &= ~(NETSERVER_THROUGHPUT|NETSERVER_LATENCY); } /* Get a socket of the right type */ if (_endpoint_is_UNIX(u)) u->fd = socket(AF_UNIX, SOCK_STREAM, 0); else if (_endpoint_is_INET6(u)) u->fd = socket(AF_INET6, SOCK_STREAM, 0); else u->fd = socket(AF_INET, SOCK_STREAM, 0); if (u->fd < 0) return NEWERROR(errno, "socket() = '%s'", strerror(errno)); if (_endpoint_is_INET(u)) sock_set_reuseaddr (u->fd, TRUE); /* Bind the socket the right way according to its type */ if (_endpoint_is_UNIX(u)) { struct sockaddr_un *sun = (struct sockaddr_un*) &ss; ss_len = sizeof(*sun); sun->sun_family = AF_UNIX; g_strlcpy(sun->sun_path, u->url, sizeof(sun->sun_path)); } else if (_endpoint_is_INET6(u)) { struct sockaddr_in6 *s6 = (struct sockaddr_in6*) &ss; ss_len = sizeof(*s6); s6->sin6_family = AF_INET6; s6->sin6_port = htons(u->port_cfg); inet_pton(AF_INET6, u->url, &(s6->sin6_addr)); } else { struct sockaddr_in *s4 = (struct sockaddr_in*) &ss; ss_len = sizeof(*s4); s4->sin_family = AF_INET; s4->sin_port = htons(u->port_cfg); inet_pton(AF_INET, u->url, &(s4->sin_addr)); } if (0 > bind(u->fd, (struct sockaddr*)&ss, ss_len)) { int errsave = errno; u->port_real = 0; if (_endpoint_is_UNIX(u)) metautils_pclose (&u->fd); return NEWERROR(errsave, "bind(%s) = '%s'", u->url, strerror(errsave)); } /* for INET sockets, get the port really used */ if (_endpoint_is_INET(u)) { memset(&ss, 0, sizeof(ss)); ss_len = sizeof(ss); getsockname(u->fd, (struct sockaddr*)&ss, &ss_len); if (_endpoint_is_INET4(u)) u->port_real = ntohs(((struct sockaddr_in*)&ss)->sin_port); else u->port_real = ntohs(((struct sockaddr_in6*)&ss)->sin6_port); } /* And finally set the mandatory fags. */ sock_set_non_blocking(u->fd, TRUE); if (0 > listen(u->fd, 32768)) return NEWERROR(errno, "listen() = '%s'", strerror(errno)); return NULL; }