00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024
00025 #ifdef HAVE_SYS_TYPES_H
00026 #include <sys/types.h>
00027 #endif
00028
00029 #ifdef HAVE_SYS_SOCKET_H
00030 #include <sys/socket.h>
00031 #endif
00032
00033 #include <fcntl.h>
00034
00035 #ifdef HAVE_ERRNO_H
00036 #include <errno.h>
00037 #endif
00038
00039 #include <stdarg.h>
00040 #include <signal.h>
00041 #include <net/if.h>
00042 #include <sys/un.h>
00043
00044 #ifdef HAVE_NETDB_H
00045 #include <netdb.h>
00046 #endif
00047
00048 #ifdef HAVE_NETINET_IN_H
00049 #include <netinet/in.h>
00050 #endif
00051
00052 #ifdef HAVE_SYS_TIME_H
00053 #include <sys/time.h>
00054 #endif
00055
00056 #ifdef HAVE_SYS_FILIO_H
00057 #include <sys/filio.h>
00058 #endif
00059
00060 #ifdef HAVE_SYS_IOCTL_H
00061 #include <sys/ioctl.h>
00062 #endif
00063
00064 #ifdef HAVE_SYS_FILIO_H
00065 #include <sys/filio.h>
00066 #endif
00067
00068 #ifdef HAVE_STRING_H
00069 #include <string.h>
00070 #endif
00071
00072 #ifdef HAVE_UNISTD_H
00073 #include <unistd.h>
00074 #endif
00075
00076 #ifdef HAVE_SYS_STAT_H
00077 #include <sys/stat.h>
00078 #endif
00079
00080 #ifdef HAVE_STROPTS_H
00081 #include <stropts.h>
00082 #endif
00083
00084 #include "monitor.h"
00085 #include "net.h"
00086 #include "ssl.h"
00087
00100
00101
00102
00112 int check_connect(char *hostname, int port, int protocol) {
00113
00114 int socket;
00115 int rv= TRUE;
00116
00117 ASSERT(hostname);
00118
00119 if ((socket= create_socket(hostname, port, protocol)) < 0) {
00120
00121 rv= FALSE;
00122
00123 } else if (! check_socket(socket)) {
00124
00125 rv= FALSE;
00126
00127 }
00128
00129 close_socket(socket);
00130
00131 return rv;
00132
00133 }
00134
00135
00141 int check_host(char *hostname) {
00142
00143 struct hostent *hp;
00144
00145 ASSERT(hostname);
00146
00147 if ((hp = gethostbyname(hostname)) == NULL) {
00148
00149 return FALSE;
00150
00151 }
00152
00153 return TRUE;
00154
00155 }
00156
00157
00166 int check_connection_io(Port_T p) {
00167
00168 ASSERT(p);
00169
00170 switch(p->type) {
00171 case SOCK_STREAM: return check_socket(p->socket);
00172 case SOCK_DGRAM: return check_udp_socket(p->socket);
00173 default: break;
00174 }
00175
00176 return FALSE;
00177
00178 }
00179
00180
00186 int check_socket(int socket) {
00187
00188 fd_set rset, wset;
00189 struct timeval tv;
00190
00191 FD_ZERO(&rset);
00192 FD_ZERO(&wset);
00193 FD_SET(socket, &rset);
00194 FD_SET(socket, &wset);
00195 tv.tv_sec= SELECT_TIMEOUT;
00196 tv.tv_usec= 0;
00197
00198 return (select(socket+1, &rset, &wset, NULL, &tv) > 0);
00199 }
00200
00201
00212 int check_udp_socket(int socket) {
00213
00214 int r;
00215 char buf[1]= {0};
00216
00217
00218
00219
00220
00221 set_noblock(socket);
00222 write(socket, buf, 1);
00223 sleep(1);
00224 r= read(socket, buf, 1);
00225 set_block(socket);
00226 if(0>r) {
00227 switch(errno) {
00228 case ECONNREFUSED: return FALSE;
00229 default: break;
00230 }
00231 }
00232
00233 return TRUE;
00234
00235 }
00236
00237
00246 int create_socket(char *hostname, int port, int protocol) {
00247
00248 int s;
00249 struct hostent *hp;
00250 struct sockaddr_in sin;
00251
00252 ASSERT(hostname);
00253
00254 if ((hp= gethostbyname(hostname)) == NULL) {
00255
00256 return -1;
00257
00258 }
00259
00260 if ((s= socket(AF_INET, protocol, 0)) < 0) {
00261
00262 return -1;
00263
00264 }
00265
00266 sin.sin_family= AF_INET;
00267 sin.sin_port= htons(port);
00268 memcpy(&sin.sin_addr, hp->h_addr, hp->h_length);
00269
00270 if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
00271
00272 close_socket(s);
00273 return -1;
00274
00275 }
00276
00277 return s;
00278
00279 }
00280
00281
00288 int create_generic_socket(Port_T pp) {
00289
00290 int socket_fd= -1;
00291
00292 ASSERT(pp);
00293
00294 if(pp->family == AF_INET) {
00295
00296 socket_fd= create_socket(pp->hostname, pp->port, pp->type);
00297
00298 } else if(pp->family == AF_UNIX) {
00299
00300 socket_fd= create_unix_socket(pp->pathname, pp->type);
00301
00302 }
00303
00304 return socket_fd;
00305
00306 }
00307
00308
00316 int create_unix_socket(char *pathname, int protocol) {
00317
00318 int s;
00319 struct sockaddr_un unixsocket;
00320
00321 ASSERT(pathname);
00322
00323 if ((s= socket(PF_UNIX, protocol, 0)) < 0) {
00324
00325 return -1;
00326
00327 }
00328
00329 unixsocket.sun_family= AF_UNIX;
00330 snprintf(unixsocket.sun_path, sizeof(unixsocket.sun_path), "%s", pathname);
00331
00332 if (connect(s, (struct sockaddr *)&unixsocket, sizeof(unixsocket)) < 0) {
00333
00334 close_socket(s);
00335 return -1;
00336
00337 }
00338
00339 return s;
00340
00341 }
00342
00343
00358 int create_server_socket(int port, int backlog, char *bindAddr) {
00359
00360 int s;
00361 int flag= 1;
00362 struct sockaddr_in myaddr;
00363
00364 if ((s= socket(AF_INET, SOCK_STREAM, 0)) < 0)
00365 return -1;
00366
00367 memset(&myaddr, 0, sizeof(struct sockaddr_in));
00368 myaddr.sin_family= AF_INET;
00369 myaddr.sin_port= htons(port);
00370
00371 if(bindAddr) {
00372 struct hostent *h= gethostbyname(bindAddr);
00373 endhostent();
00374 if(h==NULL) {
00375 errno= h_errno;
00376 goto error;
00377 }
00378 myaddr.sin_addr= *(struct in_addr*)h->h_addr_list[0];
00379 } else {
00380 myaddr.sin_addr.s_addr= htonl(INADDR_ANY);
00381 }
00382
00383 if (setsockopt(s, SOL_SOCKET,
00384 SO_REUSEADDR, (char *)&flag, sizeof(int)) < 0)
00385 goto error;
00386
00387 if (bind(s, (struct sockaddr *)&myaddr, sizeof(struct sockaddr_in)) < 0)
00388 goto error;
00389
00390 if (listen(s, backlog) < 0)
00391 goto error;
00392
00393 if (fcntl(s, F_SETFD, FD_CLOEXEC) == -1)
00394 goto error;
00395
00396 return s;
00397
00398 error:
00399 close(s);
00400
00401 return -1;
00402
00403 }
00404
00405
00411 int close_socket(int socket) {
00412
00413 int rv= TRUE;
00414
00415 if ((shutdown(socket, 2) < 0)) {
00416
00417 rv= FALSE;
00418
00419 }
00420
00421 if (close(socket) < 0) {
00422
00423 rv= FALSE;
00424
00425 }
00426
00427 return rv;
00428
00429 }
00430
00431
00439 int set_sotimeout(int socket, int timeout) {
00440
00441 struct timeval tv= {timeout, 0};
00442
00443 return ((setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv))==0) &&
00444 (setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv))==0));
00445
00446 }
00447
00448
00454 int set_noblock(int socket) {
00455
00456 int flag= 1;
00457
00458 return (! ioctl(socket, FIONBIO, &flag));
00459
00460 }
00461
00462
00468 int set_block(int socket) {
00469
00470 int flag= 0;
00471
00472 return (! ioctl(socket, FIONBIO, &flag));
00473
00474 }
00475
00485 int port_send(Port_T p, const char *msg, int len, int flags) {
00486
00487 ASSERT(p);
00488 ASSERT(msg);
00489
00490 if (p->ssl!=NULL) {
00491
00492 return send_ssl_socket(p->ssl, (void *) msg, len);
00493
00494 } else {
00495
00496 return sock_send(p->socket, msg, len, flags);
00497
00498 }
00499
00500 }
00501
00511 int port_recv(Port_T p, char *buf, int len, int flags) {
00512
00513 ASSERT(p);
00514 ASSERT(buf);
00515
00516 if (p->ssl!=NULL) {
00517 int error;
00518 error = recv_ssl_socket(p->ssl, buf, len);
00519
00520 return error;
00521
00522 } else {
00523
00524 return sock_recv(p->socket, buf, len, flags);
00525
00526 }
00527 }
00528
00529
00539 int sock_send(int sock, const char *msg, int len, int flags) {
00540
00541 int rv;
00542 fd_set fdset;
00543 struct timeval t;
00544 int retry;
00545
00546 ASSERT(msg);
00547
00548 if (! set_noblock(sock)) {
00549
00550 return -1;
00551
00552 }
00553
00554 rv= send(sock, msg, len, flags);
00555 if (rv <= 0) {
00556
00557 if (errno == EWOULDBLOCK)
00558 do {
00559
00560 retry= FALSE;
00561 FD_ZERO(&fdset);
00562 FD_SET(sock, &fdset);
00563 t.tv_sec= SELECT_TIMEOUT;
00564 t.tv_usec= 0;
00565 rv = select(sock+1, NULL, &fdset, NULL, &t);
00566 if (rv <= 0) {
00567
00568 rv= -1;
00569
00570 }
00571 else {
00572
00573 rv = send(sock, msg, len, flags);
00574 if (rv <= 0) {
00575
00576 if(errno == EWOULDBLOCK) {
00577
00578 retry= TRUE;
00579 sleep(1);
00580
00581 }
00582
00583 }
00584
00585 }
00586
00587 } while(retry);
00588
00589 }
00590
00591 set_block(sock);
00592
00593 return rv;
00594
00595 }
00596
00597
00607 int sock_recv(int sock, char *buf, int len, int flags) {
00608
00609 int rv;
00610 fd_set fdset;
00611 struct timeval t;
00612
00613 ASSERT(buf);
00614
00615 if (! set_noblock(sock)) {
00616
00617 return -1;
00618
00619 }
00620
00621 rv= recv(sock, buf, len, flags);
00622 if (rv <= 0) {
00623
00624 if (errno == EWOULDBLOCK) {
00625
00626 FD_ZERO(&fdset);
00627 FD_SET(sock, &fdset);
00628 t.tv_sec= SELECT_TIMEOUT;
00629 t.tv_usec = 0;
00630 rv = select(sock+1, &fdset, NULL, NULL, &t);
00631 if (rv <= 0) {
00632
00633 rv= -1;
00634
00635 }
00636 else {
00637
00638 rv= recv(sock, buf, len, flags);
00639
00640 }
00641
00642 }
00643
00644 }
00645
00646 set_block(sock);
00647
00648 return rv;
00649
00650 }
00651
00652
00658 char *get_localhostname() {
00659
00660 char hostname[256];
00661
00662 if (gethostname(hostname, sizeof(hostname)) < 0) {
00663
00664 return NULL;
00665
00666 }
00667
00668 return (strdup(hostname));
00669
00670 }
00671
00672
00679 char *get_remote_host(int socket) {
00680
00681 struct hostent *h;
00682 struct sockaddr_in r;
00683 int l= sizeof(struct sockaddr_in);
00684
00685 if (getpeername(socket, (struct sockaddr*)&r, &l) < 0) {
00686
00687 return NULL;
00688
00689 } else {
00690
00691 h=gethostbyaddr((char *)&r.sin_addr, sizeof(struct in_addr), AF_INET);
00692 if (h) {
00693
00694 return strdup(h->h_name);
00695
00696 }
00697
00698 }
00699
00700 return NULL;
00701
00702 }
00703