diff options
| author | osmiy <osmiy@97f52cf1-0a1b-0410-bd0e-c28be96e8082> | 2007-04-14 05:55:37 +0000 |
|---|---|---|
| committer | osmiy <osmiy@97f52cf1-0a1b-0410-bd0e-c28be96e8082> | 2007-04-14 05:55:37 +0000 |
| commit | 5ac1783eabb170049375d6cebd909c10a6523a73 (patch) | |
| tree | 4b27eec49bce906d83911e64ff173171cc6bc979 /src/libs/zbxcomms | |
| parent | eb60de08877fe0e6f42e54949bb332e02caf86c1 (diff) | |
| download | zabbix-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.c | 602 |
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;
+}
+ |
