diff --git a/include/comms.h b/include/comms.h index bb538fd..38c1fa0 100644 --- a/include/comms.h +++ b/include/comms.h @@ -69,7 +69,7 @@ void zbx_gethost_by_ip(const char *ip, char *host, size_t hostlen); #endif /* WINDOWS */ void zbx_tcp_init(zbx_sock_t *s, ZBX_SOCKET o); -int zbx_tcp_connect(zbx_sock_t *s, const char *ip, unsigned short port, int timeout); +int zbx_tcp_connect(zbx_sock_t *s, const char *ip, unsigned short port, int timeout, const char* from_ip); #define ZBX_TCP_NEW_PROTOCOL 0x01 diff --git a/misc/conf/zabbix_server.conf b/misc/conf/zabbix_server.conf index ec85ac3..bc4a10f 100644 --- a/misc/conf/zabbix_server.conf +++ b/misc/conf/zabbix_server.conf @@ -49,6 +49,9 @@ #ListenIP=127.0.0.1 +# PollerIP parameter specify which address poller's requests to agents will be bind to. +#PollerIP= + # How often ZABBIX will perform housekeeping procedure # (in hours) # Default value is 1 hour diff --git a/src/libs/zbxcomms/comms.c b/src/libs/zbxcomms/comms.c index 6b78b48..d408302 100644 --- a/src/libs/zbxcomms/comms.c +++ b/src/libs/zbxcomms/comms.c @@ -318,11 +318,12 @@ void zbx_tcp_init(zbx_sock_t *s, ZBX_SOCKET o) int zbx_tcp_connect(zbx_sock_t *s, const char *ip, unsigned short port, - int timeout + int timeout, + const char *from_ip, ) { int ret=SUCCEED; - struct addrinfo *ai, hints; + struct addrinfo *ai, hints, *from_ai; char service[MAX_STRING_LEN]; ZBX_TCP_START(); @@ -346,6 +347,22 @@ int zbx_tcp_connect(zbx_sock_t *s, goto out; } + /* if from ip specified, bind this socket to given IP address before connect */ + if (from_ip) { + memset(&hints, 0x00, sizeof(struct addrinfo)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + if (0 != getaddrinfo (from_ip, NULL, &hints, &from_ai)) { + zbx_set_tcp_strerror("Cannot resolve PollerIP [%s] [%s]", ip, strerror_from_system(zbx_sock_last_error())); + ret=FAIL; + goto out; + } + + bind (s->socket, from_ai->ai_addr, from_ai->ai_addrlen); + freeaddrinfo (from_ai); + } + if (0 != timeout) { s->timeout = timeout; #if defined(_WINDOWS) @@ -374,10 +391,11 @@ out: int zbx_tcp_connect(zbx_sock_t *s, const char *ip, unsigned short port, - int timeout + int timeout, + const char *from_ip ) { - ZBX_SOCKADDR servaddr_in; + ZBX_SOCKADDR servaddr_in, from_addr; struct hostent *hp; ZBX_TCP_START(); @@ -398,6 +416,13 @@ int zbx_tcp_connect(zbx_sock_t *s, return FAIL; } + if (from_ip) { + memset (&from_addr, 0, sizeof (ZBX_SOCKADDR)); + from_addr.sin_family = AF_INET; + from_addr.sin_addr.s_addr = inet_addr (from_ip); + bind (s->socket, (struct sockaddr*)&from_addr, sizeof (ZBX_SOCKADDR)); + } + if (0 != timeout) { s->timeout = timeout; #if defined(_WINDOWS) diff --git a/src/libs/zbxemail/email.c b/src/libs/zbxemail/email.c index 71b1f18..4b9d29a 100644 --- a/src/libs/zbxemail/email.c +++ b/src/libs/zbxemail/email.c @@ -62,7 +62,7 @@ int send_email(char *smtp_server,char *smtp_helo,char *smtp_email,char *mailto,c zabbix_log( LOG_LEVEL_DEBUG, "In send_email[smtp_server:%s]", smtp_server); - if(FAIL == zbx_tcp_connect(&s, smtp_server, 25, 0)) + if(FAIL == zbx_tcp_connect(&s, smtp_server, 25, 0, NULL)) { zbx_snprintf(error,max_error_len,"Cannot connect to SMTP server [%s] [%s]", smtp_server, zbx_tcp_strerror()); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); diff --git a/src/libs/zbxsysinfo/common/http.c b/src/libs/zbxsysinfo/common/http.c index 2998875..94ee97c 100644 --- a/src/libs/zbxsysinfo/common/http.c +++ b/src/libs/zbxsysinfo/common/http.c @@ -40,7 +40,7 @@ static int get_http_page(char *host, char *param, unsigned short port, char *buf assert(buffer); - if (SUCCEED == (ret = zbx_tcp_connect(&s, host, port, 0))) { + if (SUCCEED == (ret = zbx_tcp_connect(&s, host, port, 0, NULL))) { zbx_snprintf(request, sizeof(request), "GET /%s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n", param, host); diff --git a/src/libs/zbxsysinfo/common/net.c b/src/libs/zbxsysinfo/common/net.c index 8920135..122964b 100644 --- a/src/libs/zbxsysinfo/common/net.c +++ b/src/libs/zbxsysinfo/common/net.c @@ -47,7 +47,7 @@ int tcp_expect( *value_int = 0; - if (SUCCEED == (ret = zbx_tcp_connect(&s, host, port, 0))) { + if (SUCCEED == (ret = zbx_tcp_connect(&s, host, port, 0, NULL))) { if( NULL == request ) { *value_int = 1; diff --git a/src/libs/zbxsysinfo/simple/ntp.c b/src/libs/zbxsysinfo/simple/ntp.c index 55c227a..d22344f 100644 --- a/src/libs/zbxsysinfo/simple/ntp.c +++ b/src/libs/zbxsysinfo/simple/ntp.c @@ -190,7 +190,7 @@ int check_ntp(char *host, unsigned short port, int *value_int) *value_int = 0; - if (SUCCEED == (ret = zbx_tcp_connect(&s, host, port, 0))) { + if (SUCCEED == (ret = zbx_tcp_connect(&s, host, port, 0, NULL))) { make_packet(&data); pack_ntp((unsigned char*)packet, sizeof(packet), &data); diff --git a/src/libs/zbxsysinfo/simple/simple.c b/src/libs/zbxsysinfo/simple/simple.c index 03bb05f..b0f224e 100644 --- a/src/libs/zbxsysinfo/simple/simple.c +++ b/src/libs/zbxsysinfo/simple/simple.c @@ -118,7 +118,7 @@ static int check_ssh(const char *host, unsigned short port, int *value_int) assert(value_int); *value_int = 0; - if (SUCCEED == (ret = zbx_tcp_connect(&s, host, port, 0))) { + if (SUCCEED == (ret = zbx_tcp_connect(&s, host, port, 0, NULL))) { if( SUCCEED == (ret = zbx_tcp_recv(&s, &recv_buf)) ) { if ( 0 == strncmp(recv_buf, "SSH", 3) ) diff --git a/src/zabbix_agent/active.c b/src/zabbix_agent/active.c index ba12f0e..fcd3d98 100644 --- a/src/zabbix_agent/active.c +++ b/src/zabbix_agent/active.c @@ -263,7 +263,7 @@ static int get_active_checks( zabbix_log( LOG_LEVEL_DEBUG, "get_active_checks('%s',%u)", host, port); - if (SUCCEED == (ret = zbx_tcp_connect(&s, host, port, CONFIG_TIMEOUT))) { + if (SUCCEED == (ret = zbx_tcp_connect(&s, host, port, CONFIG_TIMEOUT, NULL))) { zbx_snprintf(packet, sizeof(packet), "%s\n%s\n","ZBX_GET_ACTIVE_CHECKS", CONFIG_HOSTNAME); zabbix_log(LOG_LEVEL_DEBUG, "Sending [%s]", packet); @@ -328,7 +328,7 @@ static int send_value( *request = NULL; int ret; - if (SUCCEED == (ret = zbx_tcp_connect(&s, host, port, CONFIG_TIMEOUT))) { + if (SUCCEED == (ret = zbx_tcp_connect(&s, host, port, CONFIG_TIMEOUT, NULL))) { request = comms_create_request(hostname, key, value, lastlogsize, timestamp, source, severity); zabbix_log(LOG_LEVEL_DEBUG, "XML before sending [%s]",request); diff --git a/src/zabbix_get/zabbix_get.c b/src/zabbix_get/zabbix_get.c index 7e5fe63..7db5227 100644 --- a/src/zabbix_get/zabbix_get.c +++ b/src/zabbix_get/zabbix_get.c @@ -144,7 +144,7 @@ static int get_value( *value = NULL; - if (SUCCEED == (ret = zbx_tcp_connect(&s, host, port, SENDER_TIMEOUT))) { + if (SUCCEED == (ret = zbx_tcp_connect(&s, host, port, SENDER_TIMEOUT, NULL))) { zbx_snprintf(request, sizeof(request),"%s\n",key); if( SUCCEED == (ret = zbx_tcp_send(&s, request)) ) { diff --git a/src/zabbix_sender/zabbix_sender.c b/src/zabbix_sender/zabbix_sender.c index 8e65928..863fbc3 100644 --- a/src/zabbix_sender/zabbix_sender.c +++ b/src/zabbix_sender/zabbix_sender.c @@ -171,7 +171,7 @@ static ZBX_THREAD_ENTRY(send_value, args) signal( SIGALRM, send_signal_handler ); #endif /* NOT _WINDOWS */ - if (SUCCEED == (tcp_ret = zbx_tcp_connect(&sock, sentdval_args->server, sentdval_args->port, SENDER_TIMEOUT))) { + if (SUCCEED == (tcp_ret = zbx_tcp_connect(&sock, sentdval_args->server, sentdval_args->port, SENDER_TIMEOUT, NULL))) { tosend = comms_create_request(sentdval_args->hostname, sentdval_args->key, sentdval_args->key_value, NULL, NULL, NULL, NULL); diff --git a/src/zabbix_server/nodewatcher/nodecomms.c b/src/zabbix_server/nodewatcher/nodecomms.c index c238d86..7ab823f 100644 --- a/src/zabbix_server/nodewatcher/nodecomms.c +++ b/src/zabbix_server/nodewatcher/nodecomms.c @@ -77,7 +77,7 @@ int send_to_node(char *name, int dest_nodeid, int nodeid, char *data) port=atoi(row[1]); DBfree_result(result); - if( FAIL == zbx_tcp_connect(&sock, ip, port, 0)) + if( FAIL == zbx_tcp_connect(&sock, ip, port, 0, NULL)) { zabbix_log(LOG_LEVEL_DEBUG, "Unable to connect to Node [%d] error: %s", dest_nodeid, zbx_tcp_strerror()); return FAIL; diff --git a/src/zabbix_server/poller/checks_agent.c b/src/zabbix_server/poller/checks_agent.c index a9a5fe8..479aa4d 100644 --- a/src/zabbix_server/poller/checks_agent.c +++ b/src/zabbix_server/poller/checks_agent.c @@ -59,7 +59,7 @@ int get_value_agent(DB_ITEM *item, AGENT_RESULT *result) item->host_ip, item->key ); - if (SUCCEED == (ret = zbx_tcp_connect(&s, item->useip==1 ? item->host_ip : item->host_dns, item->port, 0))) { + if (SUCCEED == (ret = zbx_tcp_connect(&s, item->useip==1 ? item->host_ip : item->host_dns, item->port, 0, CONFIG_POLLER_IP))) { zbx_snprintf(packet, sizeof(packet), "%s\n",item->key); zabbix_log(LOG_LEVEL_DEBUG, "Sending [%s]", packet); diff --git a/src/zabbix_server/poller/checks_agent.h b/src/zabbix_server/poller/checks_agent.h index f890eee..8a32da2 100644 --- a/src/zabbix_server/poller/checks_agent.h +++ b/src/zabbix_server/poller/checks_agent.h @@ -26,6 +26,7 @@ #include "sysinfo.h" extern int CONFIG_NOTIMEWAIT; +extern char *CONFIG_POLLER_IP; extern int get_value_agent(DB_ITEM *item, AGENT_RESULT *result); diff --git a/src/zabbix_server/server.c b/src/zabbix_server/server.c index a727784..4a65ae8 100644 --- a/src/zabbix_server/server.c +++ b/src/zabbix_server/server.c @@ -127,6 +127,7 @@ int CONFIG_UNREACHABLE_POLLER_FORKS = 1; int CONFIG_LISTEN_PORT = 10051; char *CONFIG_LISTEN_IP = NULL; +char *CONFIG_POLLER_IP = NULL; int CONFIG_TRAPPER_TIMEOUT = TRAPPER_TIMEOUT; /**/ /*int CONFIG_NOTIMEWAIT =0;*/ @@ -201,6 +202,7 @@ void init_config(void) {"UnavailableDelay",&CONFIG_UNAVAILABLE_DELAY,0,TYPE_INT,PARM_OPT,1,3600}, {"ListenIP",&CONFIG_LISTEN_IP,0,TYPE_STRING,PARM_OPT,0,0}, {"ListenPort",&CONFIG_LISTEN_PORT,0,TYPE_INT,PARM_OPT,1024,32768}, + {"PollerIP",&CONFIG_POLLER_IP,0,TYPE_STRING,PARM_OPT,0,0}, /* {"NoTimeWait",&CONFIG_NOTIMEWAIT,0,TYPE_INT,PARM_OPT,0,1},*/ /* {"DisablePinger",&CONFIG_DISABLE_PINGER,0,TYPE_INT,PARM_OPT,0,1},*/ {"DisableHousekeeping",&CONFIG_DISABLE_HOUSEKEEPING,0,TYPE_INT,PARM_OPT,0,1},