#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 <crosser@average.org>
COPYRIGHT:
Public domain
*/
#include "config.h"
#include <sys/types.h>
#include <time.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/un.h>
#include <netdb.h>
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#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;
}
syntax highlighted by Code2HTML, v. 0.9.1