summaryrefslogtreecommitdiffstats
path: root/src/libs/zbxcomms
diff options
context:
space:
mode:
authorosmiy <osmiy@97f52cf1-0a1b-0410-bd0e-c28be96e8082>2007-04-14 05:55:37 +0000
committerosmiy <osmiy@97f52cf1-0a1b-0410-bd0e-c28be96e8082>2007-04-14 05:55:37 +0000
commit5ac1783eabb170049375d6cebd909c10a6523a73 (patch)
tree4b27eec49bce906d83911e64ff173171cc6bc979 /src/libs/zbxcomms
parenteb60de08877fe0e6f42e54949bb332e02caf86c1 (diff)
downloadzabbix-5ac1783eabb170049375d6cebd909c10a6523a73.tar.gz
zabbix-5ac1783eabb170049375d6cebd909c10a6523a73.tar.xz
zabbix-5ac1783eabb170049375d6cebd909c10a6523a73.zip
- new comms protocol for ZABBIX agents
git-svn-id: svn://svn.zabbix.com/trunk@4001 97f52cf1-0a1b-0410-bd0e-c28be96e8082
Diffstat (limited to 'src/libs/zbxcomms')
-rw-r--r--src/libs/zbxcomms/comms.c602
1 files changed, 493 insertions, 109 deletions
diff --git a/src/libs/zbxcomms/comms.c b/src/libs/zbxcomms/comms.c
index 2f0a4b2e..63a20b37 100644
--- a/src/libs/zbxcomms/comms.c
+++ b/src/libs/zbxcomms/comms.c
@@ -19,8 +19,165 @@
#include "common.h"
#include "comms.h"
-#include "zbxsock.h"
-
+#include "log.h"
+
+#if defined(_WINDOWS)
+# if defined(__INT_MAX__) && __INT_MAX__ == 2147483647
+ typedef int ssize_t;
+# else
+ typedef long ssize_t;
+# endif /* __INT_MAX__ */
+
+# define ZBX_TCP_WRITE(s, b, bl) ((ssize_t)send((s), (b), (bl), 0))
+# define ZBX_TCP_READ(s, b, bl) ((ssize_t)recv((s), (b), (bl), 0))
+
+# define ZBX_TCP_ERROR SOCKET_ERROR
+# define ZBX_SOCK_ERROR INVALID_SOCKET
+
+# define zbx_sock_close(s) if( ZBX_SOCK_ERROR != (s) ) closesocket(s)
+# define zbx_sock_last_error() WSAGetLastError()
+#else
+
+# define ZBX_TCP_WRITE(s, b, bl) ((ssize_t)write((s), (b), (bl)))
+# define ZBX_TCP_READ(s, b, bl) ((ssize_t)read((s), (b), (bl)))
+
+# define ZBX_TCP_ERROR -1
+# define ZBX_SOCK_ERROR -1
+
+# define zbx_sock_close(s) if( ZBX_SOCK_ERROR != (s) ) close(s)
+# define zbx_sock_last_error() errno
+#endif /* _WINDOWS */
+
+/******************************************************************************
+ * *
+ * Function: zbx_tcp_strerror *
+ * *
+ * Purpose: return string describing of tcp error *
+ * *
+ * Parameters: *
+ * *
+ * Return value: pointer to the null terminated string *
+ * *
+ * Author: Eugene Grigorjev *
+ * *
+ * Comments: *
+ * *
+ ******************************************************************************/
+#define ZBX_TCP_MAX_STRERROR 255
+
+static char zbx_tcp_strerror_message[ZBX_TCP_MAX_STRERROR];
+
+char* zbx_tcp_strerror(void)
+{
+ zbx_tcp_strerror_message[ZBX_TCP_MAX_STRERROR - 1] = '\0'; /* forse terminate string */
+ return (&zbx_tcp_strerror_message[0]);
+}
+
+#define ZBX_TCP_ERR_START zbx_snprintf( zbx_tcp_strerror_message, ZBX_TCP_MAX_STRERROR,
+#define ZBX_TCP_ERR_END )
+
+/******************************************************************************
+ * *
+ * Function: zbx_gethost *
+ * *
+ * Purpose: retrive 'hostent' by host name and IP *
+ * *
+ * Parameters: *
+ * *
+ * Return value: hostent or NULL - an error occured *
+ * *
+ * Author: Eugene Grigorjev *
+ * *
+ * Comments: *
+ * *
+ ******************************************************************************/
+struct hostent *zbx_gethost(const char *hostname)
+{
+ unsigned int addr;
+ struct hostent* host;
+
+ assert(hostname);
+
+ host = gethostbyname(hostname);
+ if(host) return host;
+
+ addr = inet_addr(hostname);
+
+ host = gethostbyaddr((char *)&addr, 4, AF_INET);
+
+ if(host) return host;
+
+ ZBX_TCP_ERR_START "gethost() failed for address '%s' [%s]", hostname, strerror_from_system(zbx_sock_last_error()) ZBX_TCP_ERR_END;
+
+ return (struct hostent*) NULL;
+}
+
+/******************************************************************************
+ * *
+ * Function: zbx_tcp_start *
+ * *
+ * Purpose: Initialize Windows Sockets APIa *
+ * *
+ * Parameters: *
+ * *
+ * Return value: SUCCEED or FAIL - an error occured *
+ * *
+ * Author: Eugene Grigorjev *
+ * *
+ * Comments: *
+ * *
+ ******************************************************************************/
+#if defined(_WINDOWS)
+
+#define ZBX_TCP_START() { if( FAIL == tcp_started ) tcp_started = zbx_tcp_start(); }
+
+/* static (winXX threads require OFF) */ int tcp_started = FAIL;
+
+static int zbx_tcp_start(void)
+{
+ WSADATA sockInfo;
+
+ switch(WSAStartup(0x0002,&sockInfo))
+ {
+ case WSASYSNOTREADY:
+ ZBX_TCP_ERR_START "Underlying network subsystem is not ready for network communication." ZBX_TCP_ERR_END;
+ return FAIL;
+ case WSAVERNOTSUPPORTED:
+ ZBX_TCP_ERR_START "The version of Windows Sockets support requested is not provided." ZBX_TCP_ERR_END;
+ return FAIL;
+ case WSAEINPROGRESS:
+ ZBX_TCP_ERR_START "A blocking Windows Sockets 1.1 operation is in progress." ZBX_TCP_ERR_END;
+ return FAIL;
+ case WSAEPROCLIM:
+ ZBX_TCP_ERR_START "Limit on the number of tasks supported by the Windows Sockets implementation has been reached." ZBX_TCP_ERR_END;
+ return FAIL;
+ case WSAEFAULT:
+ ZBX_TCP_ERR_START "The lpWSAData is not a valid pointer." ZBX_TCP_ERR_END;
+ return FAIL;
+ }
+
+ return SUCCEED;
+}
+
+#else
+# define ZBX_TCP_START() {}
+#endif /* _WINDOWS */
+
+/******************************************************************************
+ * *
+ * Function: zbx_tcp_init *
+ * *
+ * Purpose: initialize socket *
+ * *
+ * Parameters: *
+ * *
+ * Return value: *
+ * *
+ * Author: Alexei Vladishev *
+ * *
+ * Comments: *
+ * *
+ ******************************************************************************/
void zbx_tcp_init(zbx_sock_t *s)
{
memset(s, 0, sizeof(zbx_sock_t));
@@ -42,43 +199,43 @@ void zbx_tcp_init(zbx_sock_t *s)
* Comments: *
* *
******************************************************************************/
-int zbx_tcp_connect(zbx_sock_t *s, const char *ip, int port)
+int zbx_tcp_connect(zbx_sock_t *s, const char *ip, unsigned short port)
{
- struct sockaddr_in myaddr_in;
- struct sockaddr_in servaddr_in;
- struct hostent *hp;
+ ZBX_SOCKADDR myaddr_in;
+ ZBX_SOCKADDR servaddr_in;
- memset(s, 0, sizeof(zbx_sock_t));
-
- servaddr_in.sin_family=AF_INET;
+ struct hostent *hp;
+ ZBX_TCP_START();
+
+ zbx_tcp_init(s);
+
if(NULL == (hp = zbx_gethost(ip)))
{
-/* zabbix_log( LOG_LEVEL_WARNING, "Cannot resolve [%s]", ip); */
+ ZBX_TCP_ERR_START "Cannot resolve [%s]", ip ZBX_TCP_ERR_END;
return FAIL;
}
- servaddr_in.sin_addr.s_addr=((struct in_addr *)(hp->h_addr))->s_addr;
+ 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);
- servaddr_in.sin_port=htons(port);
-
- s->socket = socket(AF_INET,SOCK_STREAM,0);
- if(s->socket == -1)
+ if( ZBX_SOCK_ERROR == (s->socket = socket(AF_INET,SOCK_STREAM,0)) )
{
-/* zabbix_log( LOG_LEVEL_WARNING, "Cannot create socket [%s:%d] [%s]", ip, port ,strerror(errno)); */
+ ZBX_TCP_ERR_START "Cannot create socket [%s:%d] [%s]", ip, port ,strerror_from_system(zbx_sock_last_error()) ZBX_TCP_ERR_END;
return FAIL;
}
- myaddr_in.sin_family = AF_INET;
- myaddr_in.sin_port=0;
- myaddr_in.sin_addr.s_addr=INADDR_ANY;
+ myaddr_in.sin_family = AF_INET;
+ myaddr_in.sin_port = 0;
+ myaddr_in.sin_addr.s_addr = INADDR_ANY;
- if( connect(s->socket,(struct sockaddr *)&servaddr_in,sizeof(struct sockaddr_in)) == -1 )
+ if( ZBX_TCP_ERROR == connect(s->socket,(struct sockaddr *)&servaddr_in,sizeof(ZBX_SOCKADDR)) )
{
-/* zabbix_log( LOG_LEVEL_WARNING, "Cannot connect to [%s:%d] [%s]", ip, port, strerror(errno)); */
+ ZBX_TCP_ERR_START "Cannot connect to [%s:%d] [%s]", ip, port, strerror_from_system(zbx_sock_last_error()) ZBX_TCP_ERR_END;
zbx_tcp_close(s);
return FAIL;
- }
+ }
return SUCCEED;
}
@@ -94,44 +251,53 @@ int zbx_tcp_connect(zbx_sock_t *s, const char *ip, int port)
* Return value: SUCCEED - success *
* FAIL - an error occured *
* *
- * Author: Alexei Vladishev *
+ * Author: Eugene Grigorjev *
* *
* Comments: *
* *
- ******************************************************************************/
-int zbx_tcp_send(zbx_sock_t *s, char *data)
+ ******************************************************************************/
+
+#define ZBX_TCP_HEADER_DATA "ZBXD"
+#define ZBX_TCP_HEADER_VERSION "\1"
+#define ZBX_TCP_HEADER ZBX_TCP_HEADER_DATA ZBX_TCP_HEADER_VERSION
+#define ZBX_TCP_HEADER_LEN 5
+
+int zbx_tcp_send_ext(zbx_sock_t *s, const char *data, unsigned char flags)
{
- ssize_t i;
- char header[5]="ZBXD\1";
- zbx_uint64_t len64;
- ssize_t written = 0;
-
- /* Write header */
- i=write(s->socket, header, 5);
- if(i == -1)
- {
- zbx_tcp_close(s);
- return FAIL;
- }
- len64 = (zbx_uint64_t)strlen(data);
+ zbx_uint64_t len64;
+
+ ssize_t i = 0,
+ written = 0;
+
+ ZBX_TCP_START();
+
+ if( flags & ZBX_TCP_NEW_PROTOCOL )
+ {
+ /* Write header */
+ if( ZBX_TCP_ERROR == ZBX_TCP_WRITE(s->socket, ZBX_TCP_HEADER, ZBX_TCP_HEADER_LEN))
+ {
+ zbx_tcp_close(s);
+ return FAIL;
+ }
- /* Write data length */
- i=write(s->socket, &len64, sizeof(len64));
- if(i == -1)
- {
- zbx_tcp_close(s);
- return FAIL;
+ len64 = (zbx_uint64_t)strlen(data);
+
+ /* Write data length */
+ if( ZBX_TCP_ERROR == ZBX_TCP_WRITE(s->socket, (char *) &len64, sizeof(len64)) )
+ {
+ zbx_tcp_close(s);
+ return FAIL;
+ }
}
- while(written<strlen(data))
+ while(written < (ssize_t)strlen(data))
{
- i=write(s->socket, data+written,strlen(data)-written);
- if(i == -1)
+ if( ZBX_TCP_ERROR == (i = ZBX_TCP_WRITE(s->socket, data+written,strlen(data)-written)) )
{
zbx_tcp_close(s);
return FAIL;
}
- written+=i;
+ written += i;
}
return SUCCEED;
@@ -154,9 +320,154 @@ int zbx_tcp_send(zbx_sock_t *s, char *data)
******************************************************************************/
void zbx_tcp_close(zbx_sock_t *s)
{
- zbx_tcp_free(s);
- if(s->socket != 0) close(s->socket);
-}
+ ZBX_TCP_START();
+
+ zbx_tcp_unaccept(s);
+
+ zbx_tcp_free(s);
+
+ zbx_sock_close(s->socket);
+}
+
+/******************************************************************************
+ * *
+ * Function: zbx_tcp_listen *
+ * *
+ * Purpose: create socket for listening *
+ * *
+ * Parameters: *
+ * *
+ * Return value: SUCCEED - success *
+ * FAIL - an error occured *
+ * *
+ * Author: Alexei Vladishev *
+ * *
+ * Comments: *
+ * *
+ ******************************************************************************/
+int zbx_tcp_listen(
+ zbx_sock_t *s,
+ const char *listen_ip,
+ unsigned short listen_port
+ )
+{
+ ZBX_SOCKADDR serv_addr;
+ int on;
+
+ ZBX_TCP_START();
+
+ zbx_tcp_init(s);
+
+ if( ZBX_SOCK_ERROR == (s->socket = socket(AF_INET,SOCK_STREAM,0)) )
+ {
+ ZBX_TCP_ERR_START "Cannot create socket [%s:%u] [%s]", listen_ip, listen_port ,strerror_from_system(zbx_sock_last_error()) ZBX_TCP_ERR_END;
+ return FAIL;
+ }
+
+ /* 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_TCP_ERR_START "Cannot setsockopt SO_REUSEADDR [%s]", strerror_from_system(zbx_sock_last_error()) ZBX_TCP_ERR_END;
+ }
+
+ /* 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_TCP_ERR_START "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())
+ ZBX_TCP_ERR_END;
+
+ return FAIL;
+ }
+
+ if( ZBX_SOCK_ERROR == listen(s->socket, SOMAXCONN) )
+ {
+ ZBX_TCP_ERR_START "Listen failed. [%s]", strerror_from_system(zbx_sock_last_error()) ZBX_TCP_ERR_END;
+ return FAIL;
+ }
+
+ return SUCCEED;
+}
+
+/******************************************************************************
+ * *
+ * Function: zbx_tcp_accept *
+ * *
+ * Purpose: permits an incoming connection attempt on a socket *
+ * *
+ * Parameters: *
+ * *
+ * Return value: SUCCEED - success *
+ * FAIL - an error occured *
+ * *
+ * Author: Eugene Grigorjev *
+ * *
+ * Comments: *
+ * *
+ ******************************************************************************/
+int zbx_tcp_accept(zbx_sock_t *s)
+{
+ ZBX_SOCKADDR serv_addr;
+ ZBX_SOCKET accepted_socket;
+
+ int nlen;
+
+ nlen = sizeof(ZBX_SOCKADDR);
+
+ zbx_tcp_unaccept(s);
+
+ if(ZBX_TCP_ERROR == (accepted_socket = (ZBX_SOCKET)accept(s->socket, (struct sockaddr *)&serv_addr, &nlen)))
+ {
+ ZBX_TCP_ERR_START "accept() failed [%s]", strerror_from_system(zbx_sock_last_error()) ZBX_TCP_ERR_END;
+ return FAIL;
+ }
+
+ s->socket2 = s->socket; /* remember main socket */
+ s->socket = accepted_socket; /* replace socket to accepted */
+ s->accepted = 1;
+
+ return SUCCEED;
+}
+
+/******************************************************************************
+ * *
+ * Function: zbx_tcp_unaccept *
+ * *
+ * Purpose: close accepted connection *
+ * *
+ * Parameters: *
+ * *
+ * Return value: *
+ * *
+ * Author: Eugene Grigorjev *
+ * *
+ * Comments: *
+ * *
+ ******************************************************************************/
+void zbx_tcp_unaccept(zbx_sock_t *s)
+{
+ if( !s->accepted ) return;
+
+ shutdown(s->socket,2);
+
+ zbx_sock_close(s->socket);
+
+ s->socket = s->socket2; /* restore main socket */
+ s->socket2 = ZBX_SOCK_ERROR;
+ s->accepted = 0;
+}
/******************************************************************************
* *
@@ -191,87 +502,160 @@ void zbx_tcp_free(zbx_sock_t *s)
* Return value: SUCCEED - success *
* FAIL - an error occured *
* *
- * Author: Alexei Vladishev *
+ * Author: Eugene Grigorjev *
* *
* Comments: *
* *
******************************************************************************/
int zbx_tcp_recv(zbx_sock_t *s, char **data)
{
- char *bufptr;
-#define ZBX_STAT_BUF_LEN 2048
-#define ZBX_BUF_LEN ZBX_STAT_BUF_LEN*8
+#define ZBX_BUF_LEN ZBX_STAT_BUF_LEN*8
+
ssize_t nbytes;
- ssize_t read_max;
ssize_t read_bytes;
int allocated, offset;
zbx_uint64_t expected_len;
- memset(s->buf_stat,0,sizeof(s->buf_stat));
+ ZBX_TCP_START();
+
+ memset(s->buf_stat, 0, sizeof(s->buf_stat));
+ *data = s->buf_stat;
+
+ read_bytes = 0;
+ s->buf_type = ZBX_BUF_TYPE_STAT;
- s->buf_type = ZBX_BUF_TYPE_STAT;
- nbytes=read(s->socket, s->buf_stat, 5);
+ nbytes = ZBX_TCP_READ(s->socket, s->buf_stat, ZBX_TCP_HEADER_LEN);
- if(nbytes==5 && strncmp(s->buf_stat,"ZBXD",4)==0 && s->buf_stat[4] == 1)
+ if( ZBX_TCP_HEADER_LEN == nbytes && 0 == strncmp(s->buf_stat, ZBX_TCP_HEADER, ZBX_TCP_HEADER_LEN) )
{
- nbytes=read(s->socket, (void *)&expected_len, sizeof(zbx_uint64_t));
-
-/* printf("Expected len: " ZBX_FS_UI64 "\n", expected_len);*/
+ nbytes = ZBX_TCP_READ(s->socket, (void *)&expected_len, sizeof(zbx_uint64_t));
/* The rest was already cleared */
- memset(s->buf_stat,0,5);
- nbytes = read(s->socket, s->buf_stat, sizeof(s->buf_stat) - 1 );
- read_max = sizeof(s->buf_stat) - 1;
-
- *data = s->buf_stat;
+ memset(s->buf_stat,0,ZBX_TCP_HEADER_LEN);
}
- else
- {
- bufptr = s->buf_stat+strlen(s->buf_stat);
-
- read_max = ZBX_STAT_BUF_LEN - strlen(s->buf_stat) -1;
- nbytes = read(s->socket, bufptr, read_max);
- expected_len = 16*1024*1024;
-
- *data = s->buf_stat;
- }
-
- read_bytes = nbytes;
-
- if(nbytes == read_max)
- {
-/* printf("Read max\n");*/
- s->buf_type = ZBX_BUF_TYPE_DYN;
- allocated = ZBX_BUF_LEN;
- s->buf_dyn=zbx_malloc(allocated);
-
- memset(s->buf_dyn,0,ZBX_BUF_LEN);
- strnscpy(s->buf_dyn, s->buf_stat, ZBX_BUF_LEN);
- offset = strlen(s->buf_dyn);
-
- while (read_bytes<expected_len && (nbytes = read(s->socket, s->buf_stat, sizeof(s->buf_stat)-2)) != -1 && nbytes != 0)
+ else if( ZBX_TCP_ERROR != nbytes )
+ {
+ read_bytes = nbytes;
+ expected_len = 16*1024*1024;
+ }
+
+ if( ZBX_TCP_ERROR != nbytes )
+ {
+ /* fill static buffer */
+ while( ZBX_TCP_ERROR != (nbytes = ZBX_TCP_READ( s->socket, s->buf_stat + read_bytes, sizeof(s->buf_stat) - read_bytes - 1)) && nbytes > 0)
+ {
+ read_bytes += nbytes;
+ }
+ s->buf_stat[read_bytes] = '\0';
+
+ if( (sizeof(s->buf_stat) - 1) == read_bytes) /* static buffer is full */
{
- s->buf_stat[nbytes]='\0';
- zbx_snprintf_alloc(&s->buf_dyn, &allocated, &offset, ZBX_BUF_LEN-1, "%s", s->buf_stat);
- read_bytes+=nbytes;
-/* printf("Read bytes %d\n", read_bytes);*/
- }
- *data = s->buf_dyn;
+ allocated = ZBX_BUF_LEN;
+
+ s->buf_type = ZBX_BUF_TYPE_DYN;
+ s->buf_dyn = zbx_malloc(allocated);
+
+ memset(s->buf_dyn,0,allocated);
+ memcpy(s->buf_dyn, s->buf_stat, sizeof(s->buf_stat));
+
+ offset = read_bytes;
+
+ /* fill dynamic buffer */
+ while( read_bytes < expected_len && ZBX_TCP_ERROR != (nbytes = ZBX_TCP_READ(s->socket, s->buf_stat, sizeof(s->buf_stat)-1)) && nbytes > 0 )
+ {
+ s->buf_stat[nbytes] = '\0';
+ zbx_snprintf_alloc(&(s->buf_dyn), &allocated, &offset, sizeof(s->buf_stat), "%s", s->buf_stat);
+ read_bytes += nbytes;
+ }
+
+ *data = s->buf_dyn;
+ }
}
- if(nbytes < 0)
+ if( ZBX_TCP_ERROR == nbytes )
{
-/* if(errno == EINTR)
- {
- zabbix_log( LOG_LEVEL_WARNING, "Read timeout");
- }
- else
- {
- zabbix_log( LOG_LEVEL_WARNING, "read() failed");
- }*/
+ ZBX_TCP_ERR_START "ZBX_TCP_READ() failed [%s]", strerror_from_system(zbx_sock_last_error()) ZBX_TCP_ERR_END;
return FAIL;
}
return SUCCEED;
-}
+}
+
+
+/******************************************************************************
+ * *
+ * Function: check_security *
+ * *
+ * Purpose: check if connection initiator is in list of IP addresses *
+ * *
+ * Parameters: sockfd - socker descriptor *
+ * ip_list - comma-delimited list of IP addresses *
+ * allow_if_empty - allow connection if no IP given *
+ * *
+ * Return value: SUCCEED - connection allowed *
+ * FAIL - connection is not allowed *
+ * *
+ * Author: Alexei Vladishev *
+ * *
+ * Comments: *
+ * *
+ ******************************************************************************/
+
+int zbx_tcp_check_security(
+ zbx_sock_t *s,
+ const char *ip_list,
+ int allow_if_empty
+ )
+{
+ ZBX_SOCKADDR name;
+ socklen_t nlen;
+
+ struct hostent *hp;
+
+ char
+ tmp[MAX_STRING_LEN],
+ sname[MAX_STRING_LEN],
+ *sip,
+ *host;
+
+ zabbix_log( LOG_LEVEL_DEBUG, "In check_security()");
+
+ if( (1 == allow_if_empty) && ( !ip_list || !*ip_list ) )
+ {
+ return SUCCEED;
+ }
+
+ nlen = sizeof(ZBX_SOCKADDR);
+ if( ZBX_TCP_ERROR != getpeername(s->socket, (struct sockaddr*)&name, &nlen))
+ {
+ ZBX_TCP_ERR_START "Connection rejected. Getpeername failed [%s]", strerror_from_system(zbx_sock_last_error()) ZBX_TCP_ERR_END;
+ return FAIL;
+ }
+ else
+ {
+ strcpy(sname, inet_ntoa(name.sin_addr));
+
+ strscpy(tmp,ip_list);
+
+ host = (char *)strtok(tmp,",");
+
+ while( NULL != host )
+ {
+ /* Allow IP addresses or DNS names for authorization */
+ if( 0 != (hp = zbx_gethost(host)))
+ {
+ sip = inet_ntoa(*((struct in_addr *)hp->h_addr));
+ if( 0 == strcmp(sname, sip))
+ {
+ ZBX_TCP_ERR_START "Connection from [%s] accepted. Allowed servers [%s] ",sname, ip_list ZBX_TCP_ERR_END;
+ return SUCCEED;
+ }
+ }
+ host = (char *)strtok(NULL,",");
+ }
+ }
+ ZBX_TCP_ERR_START "Connection from [%s] rejected. Allowed server is [%s] ",sname, ip_list ZBX_TCP_ERR_END;
+ return FAIL;
+}
+