int zbx_tcp_connect(zbx_sock_t *s, const char *source_ip, const char *ip, unsigned short port, int timeout) { ZBX_SOCKADDR servaddr_in, source_addr; struct hostent *hp; ZBX_TCP_START(); zbx_tcp_clean(s); if (NULL == (hp = gethostbyname(ip))) { #if defined(_WINDOWS) zbx_set_tcp_strerror("gethostbyname() failed for '%s': %s", ip, strerror_from_system(WSAGetLastError())); #elif defined(HAVE_HSTRERROR) zbx_set_tcp_strerror("gethostbyname() failed for '%s': [%d] %s", ip, h_errno, hstrerror(h_errno)); #else zbx_set_tcp_strerror("gethostbyname() failed for '%s': [%d]", ip, h_errno); #endif return FAIL; } servaddr_in.sin_family = AF_INET; servaddr_in.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr; servaddr_in.sin_port = htons(port); if (ZBX_SOCK_ERROR == (s->socket = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0))) { zbx_set_tcp_strerror("cannot create socket [[%s]:%d]: %s", ip, port, strerror_from_system(zbx_sock_last_error())); return FAIL; } #if !defined(_WINDOWS) && !SOCK_CLOEXEC fcntl(s->socket, F_SETFD, FD_CLOEXEC); #endif if (NULL != source_ip) { source_addr.sin_family = AF_INET; source_addr.sin_addr.s_addr = inet_addr(source_ip); source_addr.sin_port = 0; if (ZBX_TCP_ERROR == bind(s->socket, (struct sockaddr *)&source_addr, sizeof(source_addr))) { zbx_set_tcp_strerror("bind() failed: %s", strerror_from_system(zbx_sock_last_error())); return FAIL; } } if (0 != timeout) zbx_tcp_timeout_set(s, timeout); if (ZBX_TCP_ERROR == connect(s->socket, (struct sockaddr *)&servaddr_in, sizeof(servaddr_in))) { zbx_set_tcp_strerror("cannot connect to [[%s]:%d]: %s", ip, port, strerror_from_system(zbx_sock_last_error())); zbx_tcp_close(s); return FAIL; } return SUCCEED; }
int zbx_tcp_listen( zbx_sock_t *s, const char *listen_ip, unsigned short listen_port ) { ZBX_SOCKADDR serv_addr; int on, res = FAIL; ZBX_TCP_START(); zbx_tcp_clean(s); if(ZBX_SOCK_ERROR == (s->socket = socket(AF_INET,SOCK_STREAM,0))) { zbx_set_tcp_strerror("Cannot create socket [%s:%u] [%s]", listen_ip, listen_port, strerror_from_system(zbx_sock_last_error())); goto out; } /* Enable address reuse */ /* This is to immediately use the address even if it is in TIME_WAIT state */ /* http://www-128.ibm.com/developerworks/linux/library/l-sockpit/index.html */ on = 1; if( -1 == setsockopt(s->socket, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on) )) { zbx_set_tcp_strerror("Cannot setsockopt SO_REUSEADDR [%s]", strerror_from_system(zbx_sock_last_error())); } /* Create socket Fill in local address structure */ memset(&serv_addr, 0, sizeof(ZBX_SOCKADDR)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = listen_ip ? inet_addr(listen_ip) : htonl(INADDR_ANY); serv_addr.sin_port = htons((unsigned short)listen_port); /* Bind socket */ if (ZBX_SOCK_ERROR == bind(s->socket,(struct sockaddr *)&serv_addr,sizeof(ZBX_SOCKADDR)) ) { zbx_set_tcp_strerror("Cannot bind to port %u for server %s. Error [%s]. Another zabbix_agentd already running ?", listen_port, listen_ip ? listen_ip : "[ANY]", strerror_from_system(zbx_sock_last_error())); goto out; } if( ZBX_SOCK_ERROR == listen(s->socket, SOMAXCONN) ) { zbx_set_tcp_strerror("Listen failed. [%s]", strerror_from_system(zbx_sock_last_error())); goto out; } res = SUCCEED; out: return res; }
int zbx_tcp_connect(zbx_sock_t *s, const char *source_ip, const char *ip, unsigned short port, int timeout) { ZBX_SOCKADDR servaddr_in, source_addr; struct hostent *hp; ZBX_TCP_START(); zbx_tcp_clean(s); if (NULL == (hp = zbx_gethost(ip))) return FAIL; servaddr_in.sin_family = AF_INET; servaddr_in.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr; servaddr_in.sin_port = htons(port); if (ZBX_SOCK_ERROR == (s->socket = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0))) { zbx_set_tcp_strerror("Cannot create socket [%s:%d] [%s]", ip, port, strerror_from_system(zbx_sock_last_error())); return FAIL; } #if !defined(_WINDOWS) && defined(HAVE_FCNTL_H) && !SOCK_CLOEXEC fcntl(s->socket, F_SETFD, FD_CLOEXEC); #endif if (NULL != source_ip) { source_addr.sin_family = AF_INET; source_addr.sin_addr.s_addr = inet_addr(source_ip); source_addr.sin_port = 0; if (ZBX_TCP_ERROR == bind(s->socket, (struct sockaddr *)&source_addr, sizeof(ZBX_SOCKADDR))) { zbx_set_tcp_strerror("bind() failed with error %d: %s\n", zbx_sock_last_error(), strerror_from_system(zbx_sock_last_error())); return FAIL; } } if (0 != timeout) zbx_tcp_timeout_set(s, timeout); if (ZBX_TCP_ERROR == connect(s->socket, (struct sockaddr *)&servaddr_in, sizeof(ZBX_SOCKADDR))) { zbx_set_tcp_strerror("Cannot connect to [%s:%d] [%s]", ip, port, strerror_from_system(zbx_sock_last_error())); zbx_tcp_close(s); return FAIL; } return SUCCEED; }
int zbx_tcp_listen(zbx_sock_t *s, const char *listen_ip, unsigned short listen_port) { ZBX_SOCKADDR serv_addr; char *ip, *ips, *delim; int i, on, ret = FAIL; ZBX_TCP_START(); zbx_tcp_clean(s); ip = ips = (NULL == listen_ip ? NULL : strdup(listen_ip)); while (1) { delim = (NULL == ip ? NULL : strchr(ip, ',')); if (NULL != delim) *delim = '\0'; if (NULL != ip && FAIL == is_ip4(ip)) { zbx_set_tcp_strerror("incorrect IPv4 address [%s]", ip); goto out; } if (ZBX_SOCKET_COUNT == s->num_socks) { zbx_set_tcp_strerror("not enough space for socket [[%s]:%hu]", ip ? ip : "-", listen_port); goto out; } if (ZBX_SOCK_ERROR == (s->sockets[s->num_socks] = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0))) { zbx_set_tcp_strerror("socket() for [[%s]:%hu] failed: %s", ip ? ip : "-", listen_port, strerror_from_system(zbx_sock_last_error())); goto out; } #if !defined(_WINDOWS) && !SOCK_CLOEXEC fcntl(s->sockets[s->num_socks], F_SETFD, FD_CLOEXEC); #endif /* Enable address reuse */ /* This is to immediately use the address even if it is in TIME_WAIT state */ /* http://www-128.ibm.com/developerworks/linux/library/l-sockpit/index.html */ on = 1; if (ZBX_TCP_ERROR == setsockopt(s->sockets[s->num_socks], SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on))) { zbx_set_tcp_strerror("setsockopt() for [[%s]:%hu] failed: %s", ip ? ip : "-", listen_port, strerror_from_system(zbx_sock_last_error())); } memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = NULL != ip ? inet_addr(ip) : htonl(INADDR_ANY); serv_addr.sin_port = htons((unsigned short)listen_port); if (ZBX_TCP_ERROR == bind(s->sockets[s->num_socks], (struct sockaddr *)&serv_addr, sizeof(serv_addr))) { zbx_set_tcp_strerror("bind() for [[%s]:%hu] failed: %s", ip ? ip : "-", listen_port, strerror_from_system(zbx_sock_last_error())); zbx_sock_close(s->sockets[s->num_socks]); goto out; } if (ZBX_TCP_ERROR == listen(s->sockets[s->num_socks], SOMAXCONN)) { zbx_set_tcp_strerror("listen() for [[%s]:%hu] failed: %s", ip ? ip : "-", listen_port, strerror_from_system(zbx_sock_last_error())); zbx_sock_close(s->sockets[s->num_socks]); goto out; } s->num_socks++; if (NULL == ip || NULL == delim) break; *delim = ','; ip = delim + 1; } if (0 == s->num_socks) { zbx_set_tcp_strerror("zbx_tcp_listen() fatal error: unable to serve on any address [[%s]:%hu]", listen_ip ? listen_ip : "-", listen_port); goto out; } ret = SUCCEED; out: if (NULL != ips) zbx_free(ips); if (SUCCEED != ret) { for (i = 0; i < s->num_socks; i++) zbx_sock_close(s->sockets[i]); } return ret; }
int zbx_tcp_listen(zbx_sock_t *s, const char *listen_ip, unsigned short listen_port) { struct addrinfo hints, *ai = NULL, *current_ai; char port[8], *ip, *ips, *delim; int i, err, on, ret = FAIL; ZBX_TCP_START(); zbx_tcp_clean(s); memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_flags = AI_NUMERICHOST | AI_PASSIVE; hints.ai_socktype = SOCK_STREAM; zbx_snprintf(port, sizeof(port), "%hu", listen_port); ip = ips = (NULL == listen_ip ? NULL : strdup(listen_ip)); while (1) { delim = (NULL == ip ? NULL : strchr(ip, ',')); if (NULL != delim) *delim = '\0'; if (0 != (err = getaddrinfo(ip, port, &hints, &ai))) { zbx_set_tcp_strerror("cannot resolve address [[%s]:%s]: [%d] %s", ip ? ip : "-", port, err, gai_strerror(err)); goto out; } for (current_ai = ai; NULL != current_ai; current_ai = current_ai->ai_next) { if (ZBX_SOCKET_COUNT == s->num_socks) { zbx_set_tcp_strerror("not enough space for socket [[%s]:%s]", ip ? ip : "-", port); goto out; } if (PF_INET != current_ai->ai_family && PF_INET6 != current_ai->ai_family) continue; if (ZBX_SOCK_ERROR == (s->sockets[s->num_socks] = socket(current_ai->ai_family, current_ai->ai_socktype | SOCK_CLOEXEC, current_ai->ai_protocol))) { zbx_set_tcp_strerror("socket() for [[%s]:%s] failed: %s", ip ? ip : "-", port, strerror_from_system(zbx_sock_last_error())); #ifdef _WINDOWS if (WSAEAFNOSUPPORT == zbx_sock_last_error()) #else if (EAFNOSUPPORT == zbx_sock_last_error()) #endif continue; else goto out; } #if !defined(_WINDOWS) && !SOCK_CLOEXEC fcntl(s->sockets[s->num_socks], F_SETFD, FD_CLOEXEC); #endif /* enable address reuse */ /* this is to immediately use the address even if it is in TIME_WAIT state */ /* http://www-128.ibm.com/developerworks/linux/library/l-sockpit/index.html */ on = 1; if (ZBX_TCP_ERROR == setsockopt(s->sockets[s->num_socks], SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on))) { zbx_set_tcp_strerror("setsockopt() with SO_REUSEADDR for [[%s]:%s] failed: %s", ip ? ip : "-", port, strerror_from_system(zbx_sock_last_error())); } #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) if (PF_INET6 == current_ai->ai_family && ZBX_TCP_ERROR == setsockopt(s->sockets[s->num_socks], IPPROTO_IPV6, IPV6_V6ONLY, (void *)&on, sizeof(on))) { zbx_set_tcp_strerror("setsockopt() with IPV6_V6ONLY for [[%s]:%s] failed: %s", ip ? ip : "-", port, strerror_from_system(zbx_sock_last_error())); } #endif if (ZBX_TCP_ERROR == bind(s->sockets[s->num_socks], current_ai->ai_addr, current_ai->ai_addrlen)) { zbx_set_tcp_strerror("bind() for [[%s]:%s] failed: %s", ip ? ip : "-", port, strerror_from_system(zbx_sock_last_error())); zbx_sock_close(s->sockets[s->num_socks]); #ifdef _WINDOWS if (WSAEADDRINUSE == zbx_sock_last_error()) #else if (EADDRINUSE == zbx_sock_last_error()) #endif continue; else goto out; } if (ZBX_TCP_ERROR == listen(s->sockets[s->num_socks], SOMAXCONN)) { zbx_set_tcp_strerror("listen() for [[%s]:%s] failed: %s", ip ? ip : "-", port, strerror_from_system(zbx_sock_last_error())); zbx_sock_close(s->sockets[s->num_socks]); goto out; } s->num_socks++; } if (NULL != ai) { freeaddrinfo(ai); ai = NULL; } if (NULL == ip || NULL == delim) break; *delim = ','; ip = delim + 1; } if (0 == s->num_socks) { zbx_set_tcp_strerror("zbx_tcp_listen() fatal error: unable to serve on any address [[%s]:%hu]", listen_ip ? listen_ip : "-", listen_port); goto out; } ret = SUCCEED; out: if (NULL != ips) zbx_free(ips); if (NULL != ai) freeaddrinfo(ai); if (SUCCEED != ret) { for (i = 0; i < s->num_socks; i++) zbx_sock_close(s->sockets[i]); } return ret; }
int zbx_tcp_connect(zbx_sock_t *s, const char *source_ip, const char *ip, unsigned short port, int timeout) { int ret = FAIL; struct addrinfo *ai = NULL, hints; struct addrinfo *ai_bind = NULL; char service[8]; ZBX_TCP_START(); zbx_tcp_clean(s); zbx_snprintf(service, sizeof(service), "%d", port); memset(&hints, 0x00, sizeof(struct addrinfo)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; if (0 != getaddrinfo(ip, service, &hints, &ai)) { zbx_set_tcp_strerror("cannot resolve [%s]", ip); goto out; } if (ZBX_SOCK_ERROR == (s->socket = socket(ai->ai_family, ai->ai_socktype | SOCK_CLOEXEC, ai->ai_protocol))) { zbx_set_tcp_strerror("cannot create socket [[%s]:%d]: %s", ip, port, strerror_from_system(zbx_sock_last_error())); goto out; } #if !defined(_WINDOWS) && !SOCK_CLOEXEC fcntl(s->socket, F_SETFD, FD_CLOEXEC); #endif if (NULL != source_ip) { memset(&hints, 0x00, sizeof(struct addrinfo)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_NUMERICHOST; if (0 != getaddrinfo(source_ip, NULL, &hints, &ai_bind)) { zbx_set_tcp_strerror("invalid source IP address [%s]", source_ip); goto out; } if (ZBX_TCP_ERROR == bind(s->socket, ai_bind->ai_addr, ai_bind->ai_addrlen)) { zbx_set_tcp_strerror("bind() failed: %s", strerror_from_system(zbx_sock_last_error())); goto out; } } if (0 != timeout) zbx_tcp_timeout_set(s, timeout); if (ZBX_TCP_ERROR == connect(s->socket, ai->ai_addr, ai->ai_addrlen)) { zbx_set_tcp_strerror("cannot connect to [[%s]:%d]: %s", ip, port, strerror_from_system(zbx_sock_last_error())); zbx_tcp_close(s); goto out; } ret = SUCCEED; out: if (NULL != ai) freeaddrinfo(ai); if (NULL != ai_bind) freeaddrinfo(ai_bind); return ret; }
/****************************************************************************** * * * Function: zbx_tcp_init * * * * Purpose: initialize structure of zabbix socket with specified socket * * * * Author: Eugene Grigorjev * * * ******************************************************************************/ void zbx_tcp_init(zbx_sock_t *s, ZBX_SOCKET o) { zbx_tcp_clean(s); s->socket = o; }
int zbx_tcp_listen( zbx_sock_t *s, const char *listen_ip, unsigned short listen_port ) { struct addrinfo hints, *ai = NULL, *current_ai; char port[MAX_STRING_LEN]; int e, on, ret = FAIL; ZBX_TCP_START(); zbx_tcp_clean(s); memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_flags = AI_NUMERICHOST | AI_PASSIVE; hints.ai_socktype = SOCK_STREAM; zbx_snprintf(port, sizeof(port), "%d", listen_port); if(0 != (e = getaddrinfo(listen_ip, port, &hints, &ai))) { zbx_set_tcp_strerror("Cannot resolve address [[%s]:%u], error %d: %s", listen_ip, listen_port, e, gai_strerror(e)); goto out; } for(s->num_socks = 0, current_ai = ai; current_ai != NULL; current_ai = current_ai->ai_next) { if(s->num_socks == FD_SETSIZE) { break; } /* This example only supports PF_INET and PF_INET6. */ if((current_ai->ai_family != PF_INET) && (current_ai->ai_family != PF_INET6)) continue; if((s->sockets[s->num_socks] = socket(current_ai->ai_family, current_ai->ai_socktype, current_ai->ai_protocol)) == ZBX_SOCK_ERROR) { zbx_set_tcp_strerror("socket() failed with error %d: %s", zbx_sock_last_error(), strerror_from_system(zbx_sock_last_error())); continue; } /* Enable address reuse */ /* This is to immediately use the address even if it is in TIME_WAIT state */ /* http://www-128.ibm.com/developerworks/linux/library/l-sockpit/index.html */ on = 1; if(setsockopt(s->sockets[s->num_socks], SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)) == ZBX_TCP_ERROR) { zbx_set_tcp_strerror("setsockopt() failed with error %d: %s", zbx_sock_last_error(), strerror_from_system(zbx_sock_last_error())); } /* Create socket Fill in local address structure */ if(bind(s->sockets[s->num_socks], current_ai->ai_addr, current_ai->ai_addrlen) == ZBX_TCP_ERROR) { zbx_set_tcp_strerror("bind() failed with error %d: %s", zbx_sock_last_error(), strerror_from_system(zbx_sock_last_error())); zbx_sock_close(s->sockets[s->num_socks]); continue; } if(ZBX_SOCK_ERROR == listen(s->sockets[s->num_socks], SOMAXCONN) ) { zbx_set_tcp_strerror("listen() failed with error %d: %s", zbx_sock_last_error(), strerror_from_system(zbx_sock_last_error())); zbx_sock_close(s->sockets[s->num_socks]); continue; } s->num_socks++; } if(s->num_socks == 0) { zbx_set_tcp_strerror("zbx_tcp_listen() Fatal error: unable to serve on any address. [[%s]:%u]", listen_ip, listen_port); goto out; } ret = SUCCEED; out: if (NULL != ai) freeaddrinfo(ai); return ret; }
int zbx_tcp_connect(zbx_sock_t *s, const char *source_ip, const char *ip, unsigned short port, int timeout ) { ZBX_SOCKADDR servaddr_in, source_addr; struct hostent *hp; ZBX_TCP_START(); zbx_tcp_clean(s); if (NULL == (hp = zbx_gethost(ip))) { zbx_set_tcp_strerror("Cannot resolve [%s]", ip); return FAIL; } servaddr_in.sin_family = AF_INET; servaddr_in.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr; servaddr_in.sin_port = htons(port); if (ZBX_SOCK_ERROR == (s->socket = socket(AF_INET,SOCK_STREAM,0))) { zbx_set_tcp_strerror("Cannot create socket [%s:%d] [%s]", ip, port ,strerror_from_system(zbx_sock_last_error())); return FAIL; } if (NULL != source_ip) { source_addr.sin_family = AF_INET; source_addr.sin_addr.s_addr = inet_addr(source_ip); source_addr.sin_port = 0; if (ZBX_SOCK_ERROR == bind(s->socket, (struct sockaddr *)&source_addr, sizeof(ZBX_SOCKADDR)) ) { zbx_set_tcp_strerror("bind() failed with error %d: %s\n", zbx_sock_last_error(), strerror_from_system(zbx_sock_last_error())); return FAIL; } } if (0 != timeout) { s->timeout = timeout; #if defined(_WINDOWS) timeout *= 1000; if (setsockopt(s->socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout)) == ZBX_TCP_ERROR) zbx_set_tcp_strerror("setsockopt() failed with error %d: %s", zbx_sock_last_error(), strerror_from_system(zbx_sock_last_error())); if (setsockopt(s->socket, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(timeout)) == ZBX_TCP_ERROR) zbx_set_tcp_strerror("setsockopt() failed with error %d: %s", zbx_sock_last_error(), strerror_from_system(zbx_sock_last_error())); #else alarm(timeout); #endif } if (ZBX_TCP_ERROR == connect(s->socket,(struct sockaddr *)&servaddr_in,sizeof(ZBX_SOCKADDR))) { zbx_set_tcp_strerror("Cannot connect to [%s:%d] [%s]", ip, port, strerror_from_system(zbx_sock_last_error())); zbx_tcp_close(s); return FAIL; } return SUCCEED; }
int zbx_tcp_connect(zbx_sock_t *s, const char *source_ip, const char *ip, unsigned short port, int timeout ) { int ret = FAIL; struct addrinfo *ai = NULL, hints; struct addrinfo *ai_bind = NULL; char service[MAX_STRING_LEN]; ZBX_TCP_START(); zbx_tcp_clean(s); zbx_snprintf(service, sizeof(service), "%d", port); memset(&hints, 0x00, sizeof(struct addrinfo)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; if (0 != getaddrinfo(ip, service, &hints, &ai)) { zbx_set_tcp_strerror("Cannot resolve [%s]", ip); goto out; } if (ZBX_SOCK_ERROR == (s->socket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol))) { zbx_set_tcp_strerror("Cannot create socket [%s]:%d [%s]", ip, port ,strerror_from_system(zbx_sock_last_error())); goto out; } if (NULL != source_ip) { memset(&hints, 0x00, sizeof(struct addrinfo)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_NUMERICHOST; if (0 != getaddrinfo(source_ip, NULL, &hints, &ai_bind)) { zbx_set_tcp_strerror("Invalid source IP address [%s]\n", source_ip); goto out; } if (ZBX_TCP_ERROR == bind(s->socket, ai_bind->ai_addr, ai_bind->ai_addrlen)) { zbx_set_tcp_strerror("bind() failed with error %d: %s\n", zbx_sock_last_error(), strerror_from_system(zbx_sock_last_error())); goto out; } } if (0 != timeout) { s->timeout = timeout; #if defined(_WINDOWS) timeout *= 1000; if (setsockopt(s->socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout)) == ZBX_TCP_ERROR) zbx_set_tcp_strerror("setsockopt() failed with error %d: %s", zbx_sock_last_error(), strerror_from_system(zbx_sock_last_error())); if (setsockopt(s->socket, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(timeout)) == ZBX_TCP_ERROR) zbx_set_tcp_strerror("setsockopt() failed with error %d: %s", zbx_sock_last_error(), strerror_from_system(zbx_sock_last_error())); #else alarm(timeout); #endif } if (ZBX_TCP_ERROR == connect(s->socket, ai->ai_addr, ai->ai_addrlen)) { zbx_set_tcp_strerror("*** Cannot connect to [%s]:%d [%s]", ip, port, strerror_from_system(zbx_sock_last_error())); zbx_tcp_close(s); goto out; } ret = SUCCEED; out: if (NULL != ai) freeaddrinfo(ai); if (NULL != ai_bind) freeaddrinfo(ai_bind); return ret; }