#ifndef LINT static char *rcsid="$Id: clnt_udp.c,v 1.13 1999/10/03 21:18:03 crosser Exp $"; #endif /* $Log: clnt_udp.c,v $ Revision 1.13 1999/10/03 21:18:03 crosser First (probably) working version with new run time config parser. Also added listenq parameter (backlog size for listen()) and renamed wtest to whoson (and with man page). Release 2.00beta1. Revision 1.12 1999/08/19 17:22:14 crosser Move to new config scheme (does not work yet) Revision 1.11 1999/07/27 17:30:05 crosser fix names Revision 1.10 1999/01/30 14:45:43 crosser def for buffers Revision 1.9 1999/01/30 14:41:05 crosser fix reporting addresses (used to overwrite static buffer) Revision 1.8 1998/07/28 17:51:53 crosser make 64bit architecure happy Revision 1.7 1998/07/26 14:06:40 crosser Add source address checking in UDP client Revision 1.6 1998/07/12 16:43:57 crosser Change protocol: responce now is terminated with empty line Revision 1.5 1998/07/05 00:26:18 crosser Change copyright Revision 1.4 1998/07/03 11:10:39 crosser fix include sys/time.h Revision 1.3 1998/07/02 18:01:15 crosser change error reporting to syslog Revision 1.2 1998/07/02 15:37:07 crosser check perms fix bug with excessive retries Revision 1.1 1998/07/01 21:55:16 crosser Initial revision Revision 1.2 1998/07/01 05:18:09 crosser minor warnings fix Revision 1.1 1998/07/01 05:01:22 crosser Initial revision Revision 1.1 1998/05/05 19:08:16 crosser Initial revision */ /* WHAT IS IT: Implementation of experimental "whoson" protocol AUTHOR: Eugene G. Crosser COPYRIGHT: Public domain */ #include "config.h" #include #include #include #include #include #include #include #include #ifdef HAVE_SYS_SELECT_H #include #endif #include #include #include #include #include #include #include #include #include "whoson.h" #include "rtconfig.h" #include "checkperm.h" #include "clnt_common.h" #include "report.h" #include "rtc_begin.h" #include "clnt_udp_cfg.h" #include "rtc_middle.h" #include "clnt_udp_cfg.h" #include "rtc_end.h" #define MAXREQL 1024 #define INITTIMEOUT 100000 #define MAXTRIES 5 #define MAXREREADS 20 int wso_udp_clnt_connect(void *priv,char *buf) { wso_clnt_udp_cfg *rec=(wso_clnt_udp_cfg *)(priv); struct sockaddr_in server,frominet; struct protoent *pe; int protonum; int fd; int len,slen; fd_set rfds,wfds,efds; struct timeval seltimer; unsigned long timeout; int tries,rereads,rc=0; char wbuf[MAXREQL]; char addr1a[16],addr2a[16]; memset((char *)&server,0,sizeof(server)); server.sin_family = AF_INET; if ((pe=getprotobyname("udp"))) protonum=pe->p_proto; else protonum=17; server.sin_port=htons(rec->port); server.sin_addr=rec->address; if ((fd=socket(AF_INET,SOCK_DGRAM,protonum)) < 0) { ERRLOG((LOG_ERR,"[WHOSON] server socket: %m")) return -1; } strncpy(wbuf,buf,sizeof(wbuf)-1); wbuf[sizeof(wbuf)-1]='\0'; timeout=rec->inittimeout; for (tries=0;tries<(rec->maxtries);tries++) { len=strlen(wbuf); if (sendto(fd,wbuf,len,0,(struct sockaddr *)&server, sizeof(server)) != len) { ERRLOG((LOG_ERR,"[WHOSON] sendto: %m")) close(fd); return -1; } rereads=0; reread: DPRINT(("udp waiting try=%d(%d max) timeout=%lu (init %u)\n", tries,rec->maxtries,timeout,rec->inittimeout)) seltimer.tv_sec=timeout/1000000L; seltimer.tv_usec=timeout%1000000L; DPRINT(("seltimer.tv_sec=%lu, seltimer.tv_usec=%lu\n", (long)seltimer.tv_sec, (long)seltimer.tv_usec)) FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds); FD_SET(fd,&rfds); rc=select(fd+1,&rfds,&wfds,&efds,&seltimer); if (rc < 0) { ERRLOG((LOG_ERR,"[WHOSON] select: %m")) close(fd); return -1; } else if (rc > 0) { slen=sizeof(frominet); if ((len=recvfrom(fd,buf,MAXREQL-1,0, (struct sockaddr *) &frominet, &slen)) < 0) { ERRLOG((LOG_ERR,"[WHOSON] recvfrom: %m")) close(fd); return -1; } buf[len]='\0'; if (rec->perms) { if (wso_perm_check(rec->perms, ntohl(frominet.sin_addr.s_addr))) break; } else { if (memcmp(&frominet.sin_addr.s_addr, &server.sin_addr.s_addr, sizeof(frominet.sin_addr.s_addr)) == 0) break; } strcpy(addr1a,inet_ntoa(frominet.sin_addr)); strcpy(addr2a,inet_ntoa(server.sin_addr)); ERRLOG((LOG_ERR,"[WHOSON] ignore from %s (dest was %s)", addr1a,addr2a)) if (++rereads < MAXREREADS) goto reread; else sprintf(buf,"*Ignoring from %s, sent to %s\r\n\r\n", addr1a,addr2a); } timeout *= 2; } if (rc == 0) { ERRLOG((LOG_ERR,"[WHOSON] udp excessive retries\n")) close(fd); return -1; } close(fd); return 0; }