core of overlay mode getting closer.

Compiles. With -N start to try to send regular packets.
This commit is contained in:
gardners 2011-08-08 22:41:46 +08:00
parent 6e172c76c9
commit 92768cdcd0
9 changed files with 478 additions and 174 deletions

View File

@ -1,10 +1,10 @@
SRCS= dna.c server.c client.c peers.c ciphers.c responses.c packetformats.c dataformats.c \
hlrdata.c srandomdev.c simulate.c batman.c export.c gateway.c \
overlay.c overlay_buffer.c overlay_interface.c
overlay.c overlay_buffer.c overlay_interface.c overlay_payload.c overlay_route.c
OBJS= dna.o server.o client.o peers.o ciphers.o responses.o packetformats.o dataformats.o \
hlrdata.o srandomdev.o simulate.o batman.o export.o gateway.o \
overlay.o overlay_buffer.o overlay_interface.o
overlay.o overlay_buffer.o overlay_interface.o overlay_payload.o overlay_route.o
HDRS= Makefile mphlr.h
LDFLAGS= -L/Developer/SDKs/MacOSX10.6.sdk/usr/lib
CFLAGS= -I/Developer/SDKs/MacOSX10.6.sdk/usr/include

View File

@ -1,10 +1,10 @@
SRCS= dna.c server.c client.c peers.c ciphers.c responses.c packetformats.c dataformats.c \
hlrdata.c srandomdev.c simulate.c batman.c export.c gateway.c \
overlay.c overlay_buffer.c overlay_interface.c
overlay.c overlay_buffer.c overlay_interface.c overlay_payload.c overlay_route.c
OBJS= dna.o server.o client.o peers.o ciphers.o responses.o packetformats.o dataformats.o \
hlrdata.o srandomdev.o simulate.o batman.o export.o gateway.o \
overlay.o overlay_buffer.o overlay_interface.o
overlay.o overlay_buffer.o overlay_interface.o overlay_payload.o overlay_route.o
HDRS= Makefile mphlr.h
LDFLAGS= @LDFLAGS@
CFLAGS= @CFLAGS@

1
dna.c
View File

@ -291,6 +291,7 @@ int main(int argc,char **argv)
case 'N': /* Ask for overlay network to setup one or more interfaces */
if (overlay_interface_args(optarg))
return WHY("Invalid interface specification(s) passed to -N");
overlayMode=1;
break;
case 'G': /* Offer gateway services */
gatewayuri=strdup(optarg);

30
mphlr.h
View File

@ -71,9 +71,9 @@ struct in_addr {
//FIXME #include <getopt.h>
#include <ctype.h>
/* UDP Port numbers for various Serval services */
/* UDP Port numbers for various Serval services.
The overlay mesh works over DNA */
#define PORT_DNA 4110
#define PORT_OVERLAY 4119
/* OpenWRT libc doesn't have bcopy, but has memmove */
#define bcopy(A,B,C) memmove(B,A,C)
@ -351,6 +351,7 @@ int asteriskObtainGateway(char *requestor_sid,char *did,char *uri_out);
#define CRYPT_SIGNED 2
#define CRYPT_PUBLIC 4
extern int overlayMode;
#define OVERLAY_INTERFACE_UNKNOWN 0
#define OVERLAY_INTERFACE_ETHERNET 1
#define OVERLAY_INTERFACE_WIFI 2
@ -372,6 +373,17 @@ typedef struct overlay_interface {
These figures will be refined over time, and we will allow people to set them per-interface.
*/
int tick_ms;
/* The time of the last tick on this interface in milli seconds */
long long last_tick_ms;
/* Broadcast address and netmask, if known */
struct sockaddr_in broadcast_address;
struct sockaddr_in netmask;
/* Not necessarily the real MTU, but the largest frame size we are willing to TX on this interface.
For radio links the actual maximum and the maximum that is likely to be delivered reliably are
potentially two quite different values. */
int mtu;
} overlay_interface;
/* Maximum interface count is rather arbitrary.
@ -473,6 +485,9 @@ typedef struct overlay_payload {
/* make the payload pointer be at the end, so that we can conveniently have the data follow this structure if necessary.
(this lets us change the char * to a char payload[1] down the track to simplify this) */
unsigned char *payload;
/* time this frame was enqueued */
long long enqueued_at;
} overlay_payload;
typedef struct overlay_txqueue {
@ -514,6 +529,17 @@ int ob_append_bytes(overlay_buffer *b,unsigned char *bytes,int count);
int ob_append_short(overlay_buffer *b,unsigned short v);
int ob_append_int(overlay_buffer *b,unsigned int v);
int op_free(overlay_payload *p);
long long parse_quantity(char *q);
int overlay_init_interface(in_addr_t src_addr,int speed_in_bits,int port,int type);
int overlay_interface_discover();
int overlay_interface_discover();
long long overlay_time_until_next_tick();
int overlay_rx_messages();
int overlay_check_ticks();
int overlay_add_selfannouncement();
int overlay_payload_package_fmt1(overlay_payload *p,overlay_buffer *b);
extern int overlay_interface_count;

110
overlay.c
View File

@ -37,117 +37,15 @@
frames from every call if we know that this can be safely done. That is, when traffic is low, we maximise redundancy, and when we
start to hit the limit of traffic, we start to throw away some of the redundancy. This of course relies on us knowing when the
network channel is getting too full.
This file currently seems to exist solely to contain this introduction, which is fine with me. Functions land in here until their
proper place becomes apparent.
*/
#include "mphlr.h"
int overlay_socket=-1;
int ob_unlimitsize(overlay_buffer *b);
int overlayMode=0;
overlay_txqueue overlay_tx[4];
int overlay_payload_verify()
{
/* Make sure that an incoming payload has a valid signature from the sender.
This is used to prevent spoofing */
return WHY("function not implemented");
}
int overlay_get_nexthop(overlay_payload *p,unsigned char *hopout,int *hopaddrlen)
{
return WHY("function not implemented");
}
int overlay_payload_package_fmt1(overlay_payload *p,overlay_buffer *b)
{
/* Convert a payload structure into a series of bytes.
Also select next-hop address to help payload get to its' destination */
unsigned char nexthop[SIDDIDFIELD_LEN+1];
int nexthoplen=0;
overlay_buffer *headers=ob_new(256);
if (!headers) return WHY("could not allocate overlay buffer for headers");
if (!p) return WHY("p is NULL");
if (!b) return WHY("b is NULL");
/* Build header */
int fail=0;
if (overlay_get_nexthop(p,nexthop,&nexthoplen)) fail++;
if (ob_append_bytes(headers,nexthop,nexthoplen)) fail++;
/* XXX Can use shorter fields for different address types, and if we know that the next hop
knows a short-hand for the address.
XXX Need a prefix byte for the type of address being used.
BETTER - We just insist that the first byte of Curve25519 addresses be >0x0f, and use
the low numbers for special cases:
*/
if (p->src[0]<0x10||p->dst[0]<0x10) {
// Make sure that addresses do not overload the special address spaces of 0x00*-0x0f*
fail++;
return WHY("address begins with reserved value 0x00-0x0f");
}
if (ob_append_bytes(headers,(unsigned char *)p->src,SIDDIDFIELD_LEN)) fail++;
if (ob_append_bytes(headers,(unsigned char *)p->dst,SIDDIDFIELD_LEN)) fail++;
if (fail) {
ob_free(headers);
return WHY("failure count was non-zero");
}
/* Write payload format plus total length of header bits */
if (ob_makespace(b,2+headers->length+p->payloadLength)) {
/* Not enough space free in output buffer */
ob_free(headers);
return WHY("Could not make enough space free in output buffer");
}
/* Package up headers and payload */
ob_checkpoint(b);
if (ob_append_short(b,0x1000|(p->payloadLength+headers->length)))
{ fail++; WHY("could not append version and length bytes"); }
if (ob_append_bytes(b,headers->bytes,headers->length))
{ fail++; WHY("could not append header"); }
if (ob_append_bytes(b,p->payload,p->payloadLength))
{ fail++; WHY("could not append payload"); }
/* XXX SIGN &/or ENCRYPT */
ob_free(headers);
if (fail) { ob_rewind(b); return WHY("failure count was non-zero"); } else return 0;
}
overlay_payload *overlay_payload_unpackage(overlay_buffer *b) {
/* Extract the payload at the current location in the buffer. */
WHY("not implemented");
return NULL;
}
int overlay_payload_enqueue(int q,overlay_payload *p,int urgentP)
{
/* Add payload p to queue q.
If urgentP is set, then ask for the payload queue to be sent now.
*/
return WHY("not implemented");
if (urgentP) overlay_push_queued();
}
int overlay_push_queued()
{
/* Try to send frames.
The trick here is that we need to aggregate payloads based on which interface they need to go to */
return WHY("not implemented");
}

View File

@ -1,5 +1,9 @@
#include "mphlr.h"
#ifdef HAVE_IFADDRS_H
#include <ifaddrs.h>
#endif
int overlay_ready=0;
int overlay_interface_count=0;
overlay_interface overlay_interfaces[OVERLAY_MAX_INTERFACES];
@ -108,6 +112,12 @@ int overlay_init_interface(in_addr_t src_addr,int speed_in_bits,int port,int typ
I(bits_per_second)=speed_in_bits;
I(port)=bind_addr.sin_port;
I(type)=type;
I(tick_ms)=500;
switch(type) {
case OVERLAY_INTERFACE_PACKETRADIO: I(tick_ms)=15000; break;
case OVERLAY_INTERFACE_ETHERNET: I(tick_ms)=500; break;
case OVERLAY_INTERFACE_WIFI: I(tick_ms)=500; break;
}
overlay_interface_count++;
#undef I(X)
@ -126,7 +136,7 @@ int overlay_rx_messages()
{
}
return 0;
return WHY("Not implemented");
}
int overlay_tx_messages()
@ -147,14 +157,14 @@ int overlay_tx_messages()
return 0;
}
int overlay_broadcast_ensemble(int interface_number,char *bytes,int len)
int overlay_broadcast_ensemble(int interface_number,unsigned char *bytes,int len)
{
struct sockaddr_in s;
memset(&s, '\0', sizeof(struct sockaddr_in));
s = overlay_interfaces[interface_number].broadcast_address;
s.sin_family = AF_INET;
s.sin_port = htons( PORT_OVERLAY );
s.sin_addr.s_addr = htonl( INADDR_BROADCAST );
s.sin_port = htons( overlay_interfaces[interface_number].port );
if(sendto(overlay_interfaces[interface_number].socket, bytes, len, 0, (struct sockaddr *)&s, sizeof(struct sockaddr_in)) < 0)
/* Failed to send */
@ -163,3 +173,182 @@ int overlay_broadcast_ensemble(int interface_number,char *bytes,int len)
/* Sent okay */
return 0;
}
int overlay_interface_discover()
{
#ifdef HAVE_IFADDRS_H
struct ifaddrs *ifaddr,*ifa;
int family;
if (getifaddrs(&ifaddr) == -1) {
perror("getifaddr()");
return WHY("getifaddrs() failed");
}
for (ifa=ifaddr;ifa!=NULL;ifa=ifa->ifa_next) {
family=ifa->ifa_addr->sa_family;
switch(family) {
case AF_INET:
{
unsigned char *name=(unsigned char *)ifa->ifa_name;
unsigned int local=(((struct sockaddr_in *)(ifa->ifa_addr))->sin_addr.s_addr);
unsigned int netmask=(((struct sockaddr_in *)(ifa->ifa_netmask))->sin_addr.s_addr);
unsigned int broadcast=local|~netmask;
printf("%s: %08x %08x %08x\n",name,local,netmask,broadcast);
/* XXX now register the interface, or update the existing interface registration */
break;
}
}
}
#endif
return 0;
}
int overlay_tick_interface(int i, long long now)
{
int frame_pax=0;
#define MAX_FRAME_PAX 1024
overlay_payload *pax[MAX_FRAME_PAX];
if (overlay_interfaces[i].bits_per_second<1) {
/* An interface with no speed budget is for listening only, so doesn't get ticked */
return 0;
}
fprintf(stderr,"Ticking interface #%d\n",i);
/* Get a buffer ready, and limit it's size appropriately.
XXX size limit should be reduced from MTU.
XXX we should also take account of the volume of data likely to be in the TX buffer. */
overlay_buffer *e=ob_new(overlay_interfaces[i].mtu);
if (!e) return WHY("ob_new() failed");
ob_limitsize(e,overlay_interfaces[i].mtu);
/* 0. Setup Serval Mesh frame header. We do not use an explicit length field for these, as the various
component payloads are all self-authenticating, or at least that is the theory. */
unsigned char bytes[]={/* Magic */ 'O',0x10,
/* Version */ 0x00,0x01};
ob_append_bytes(e,bytes,4);
/* 1. Send announcement about ourselves, including one SID that we host if we host more than one SID
(the first SID we host becomes our own identity, saving a little bit of data here).
*/
overlay_add_selfannouncement(i,e);
/* 2. Add any queued high-priority isochronous data (i.e. voice) to the frame. */
overlay_payload **p=&overlay_tx[OVERLAY_ISOCHRONOUS_VOICE].first;
while(p)
{
/* Throw away any stale frames */
overlay_payload *pp=*p;
if (!pp) break;
if (now>((*p)->enqueued_at+200)) {
/* Stale, so remove from queue */
*p=pp->next;
pp->next->prev=*p;
op_free(p);
}
else
{
/* XXX Filter for those which should be sent via this interface.
To do that we need to know the nexthop, and the best route to the next hop. */
/* We keep trying to queue frames in case they will fit, as not all frames are of equal size.
This means that lower bit-rate codecs will get higher priority, which is probably not all
bad. The only hard limit is the maximum number of payloads we allow in a frame, which is
set so high as to be irrelevant, even on loopback or gigabit ethernet interface */
if (frame_pax>=MAX_FRAME_PAX) break;
if (!overlay_payload_package_fmt1(*p,e))
{
/* Add payload to list of payloads we are sending with this frame so that we can dequeue them
if we send them. */
pax[frame_pax++]=*p;
}
p=&(*p)->next;
}
}
/* 3. Add some mesh reachability reports (unlike BATMAN we announce reachability to peers progressively).
Give priority to newly observed nodes so that good news travels quickly to help roaming.
XXX - Don't forget about PONGing reachability reports to allow use of monodirectional links.
*/
/* 4. XXX Add lower-priority queued data */
/* 5. XXX Fill the packet up to a suitable size with anything that seems a good idea */
/* Now send the frame. This takes the form of a special DNA packet with a different
service code, which we setup earlier. */
if (!overlay_broadcast_ensemble(i,e->bytes,e->length))
{
fprintf(stderr,"Successfully transmitted tick frame on interface #%d\n",i);
/* De-queue the passengers who were aboard. */
int j;
overlay_payload **p=&overlay_tx[OVERLAY_ISOCHRONOUS_VOICE].first;
for(j=0;j<frame_pax;j++)
{
/* Skip any frames that didn't get queued */
while ((*p)&&(*p!=pax[j])) p=&(*p)->next;
/* Now get rid of this frame once we have found it */
if (*p) {
*p=pax[j]->next;
if (pax[j]->next) pax[j]->next->prev=pax[j]->prev;
if (op_free(pax[j])) WHY("op_free() failed");
}
}
return 0;
}
else WHY("overlay_broadcast_ensemble() failed");
}
int overlay_check_ticks()
{
/* Check if any interface(s) are due for a tick */
int i;
struct timeval nowtv;
long long now;
if (gettimeofday(&nowtv,NULL))
return WHY("gettimeofday() failed");
/* Get current time in milliseconds */
now=nowtv.tv_sec*1000;
now=now+nowtv.tv_usec/1000;
/* Now check if the next tick time for the interfaces is no later than that time.
If so, trigger a tick on the interface. */
for(i=0;i<overlay_interface_count;i++)
{
if (now>=overlay_interfaces[i].last_tick_ms+overlay_interfaces[i].tick_ms)
{
/* This interface is due for a tick */
overlay_tick_interface(i,now);
overlay_interfaces[i].last_tick_ms=now;
}
}
return 0;
}
long long overlay_time_until_next_tick()
{
/* By default only tick once per day */
long long nexttick=86400*1000;
long long now;
struct timeval tv;
gettimeofday(&tv,NULL);
now=tv.tv_sec*1000+tv.tv_usec/1000;
int i;
for(i=0;i<overlay_interface_count;i++)
{
long long thistick=(overlay_interfaces[i].last_tick_ms+overlay_interfaces[i].tick_ms)-now;
if (thistick<0) thistick=0;
if (thistick<nexttick) nexttick=thistick;
}
return nexttick;
}

100
overlay_payload.c Normal file
View File

@ -0,0 +1,100 @@
#include "mphlr.h"
int overlay_payload_verify(overlay_payload *p)
{
/* Make sure that an incoming payload has a valid signature from the sender.
This is used to prevent spoofing */
return WHY("function not implemented");
}
int overlay_payload_package_fmt1(overlay_payload *p,overlay_buffer *b)
{
/* Convert a payload structure into a series of bytes.
Also select next-hop address to help payload get to its' destination */
unsigned char nexthop[SIDDIDFIELD_LEN+1];
int nexthoplen=0;
overlay_buffer *headers=ob_new(256);
if (!headers) return WHY("could not allocate overlay buffer for headers");
if (!p) return WHY("p is NULL");
if (!b) return WHY("b is NULL");
/* Build header */
int fail=0;
if (overlay_get_nexthop(p,nexthop,&nexthoplen)) fail++;
if (ob_append_bytes(headers,nexthop,nexthoplen)) fail++;
/* XXX Can use shorter fields for different address types, and if we know that the next hop
knows a short-hand for the address.
XXX Need a prefix byte for the type of address being used.
BETTER - We just insist that the first byte of Curve25519 addresses be >0x0f, and use
the low numbers for special cases:
*/
if (p->src[0]<0x10||p->dst[0]<0x10) {
// Make sure that addresses do not overload the special address spaces of 0x00*-0x0f*
fail++;
return WHY("address begins with reserved value 0x00-0x0f");
}
if (ob_append_bytes(headers,(unsigned char *)p->src,SIDDIDFIELD_LEN)) fail++;
if (ob_append_bytes(headers,(unsigned char *)p->dst,SIDDIDFIELD_LEN)) fail++;
if (fail) {
ob_free(headers);
return WHY("failure count was non-zero");
}
/* Write payload format plus total length of header bits */
if (ob_makespace(b,2+headers->length+p->payloadLength)) {
/* Not enough space free in output buffer */
ob_free(headers);
return WHY("Could not make enough space free in output buffer");
}
/* Package up headers and payload */
ob_checkpoint(b);
if (ob_append_short(b,0x1000|(p->payloadLength+headers->length)))
{ fail++; WHY("could not append version and length bytes"); }
if (ob_append_bytes(b,headers->bytes,headers->length))
{ fail++; WHY("could not append header"); }
if (ob_append_bytes(b,p->payload,p->payloadLength))
{ fail++; WHY("could not append payload"); }
/* XXX SIGN &/or ENCRYPT */
ob_free(headers);
if (fail) { ob_rewind(b); return WHY("failure count was non-zero"); } else return 0;
}
overlay_payload *overlay_payload_unpackage(overlay_buffer *b) {
/* Extract the payload at the current location in the buffer. */
WHY("not implemented");
return NULL;
}
int overlay_payload_enqueue(int q,overlay_payload *p)
{
/* Add payload p to queue q.
*/
return WHY("not implemented");
}
int op_free(overlay_payload *p)
{
if (!p) return WHY("Asked to free NULL");
if (p->prev&&p->prev->next==p) return WHY("p->prev->next still points here");
if (p->next&&p->next->prev==p) return WHY("p->next->prev still points here");
p->prev=NULL;
p->next=NULL;
if (p->payload) free(p->payload);
p->payload=NULL;
free(p);
return 0;
}

11
overlay_route.c Normal file
View File

@ -0,0 +1,11 @@
#include "mphlr.h"
int overlay_add_selfannouncement(overlay_buffer *b)
{
return WHY("Not implemented");
}
int overlay_get_nexthop(overlay_payload *p,unsigned char *nexthop,int *nexthoplen)
{
return WHY("Not implemented");
}

195
server.c
View File

@ -28,13 +28,85 @@ struct sockaddr recvaddr;
struct in_addr client_addr;
int client_port;
int getBackingStore(char *s,int size);
int createServerSocket();
int simpleServerMode();
int server(char *backing_file,int size,int foregroundMode)
{
struct sockaddr_in bind_addr;
/* Get backing store */
if (!backing_file)
/* Get backing store for HLR */
getBackingStore(backing_file,size);
if (overlayMode)
{
/* Now find and initialise all the suitable network interfaces, i.e.,
those running IPv4.
Packet radio dongles will get discovered later as the interfaces get probed.
This will setup the sockets for the server to communicate on each interface.
XXX - Problems may persist where the same address is used on multiple interfaces,
but otherwise hopefully it will allow us to bridge multiple networks.
*/
overlay_interface_discover();
}
else
{
/* Create a simple socket for listening on if we are not in overlay mesh mode. */
createServerSocket();
}
/* Detach from the console */
if (!foregroundMode) daemon(0,0);
if (!overlayMode) simpleServerMode();
else {
/* In overlay mode we need to listen to all of our sockets, and also to
send periodic traffic. This means we need to */
fprintf(stderr,"Running in overlay mode.\n");
/* Get the set of socket file descriptors we need to monitor */
int i;
fd_set read_fds;
int maxfd=-1;
FD_ZERO(&read_fds);
for(i=0;i<overlay_interface_count;i++)
{
if (overlay_interfaces[i].socket>maxfd) maxfd=overlay_interfaces[i].socket;
FD_SET(overlay_interfaces[i].socket,&read_fds);
}
while(1) {
/* Work out how long we can wait before we need to tick */
long long ms=overlay_time_until_next_tick();
struct timeval waittime;
waittime.tv_usec=(ms%1000)*1000;
waittime.tv_sec=ms/1000;
fprintf(stderr,"%d,%d\n",waittime.tv_sec,waittime.tv_usec);
int r=select(maxfd+1,&read_fds,NULL,NULL,&waittime);
if (r<0) {
/* select had a problem */
perror("select()");
return WHY("select() complained.");
} else if (r>0) {
/* We have data, so try to receive it */
overlay_rx_messages();
} else {
/* No data before tick occurred, so do nothing. */
}
/* Check if we need to trigger any ticks on any interfaces */
overlay_check_ticks();
}
}
return 0;
}
int getBackingStore(char *backing_file,int size)
{
if (!backing_file)
{
/* transitory storage of HLR data, so just malloc() the memory */
hlr=calloc(size,1);
@ -77,60 +149,7 @@ int server(char *backing_file,int size,int foregroundMode)
size,backing_file);
}
hlr_size=size;
sock=socket(PF_INET,SOCK_DGRAM,0);
if (sock<0) {
fprintf(stderr,"Could not create UDP socket.\n");
perror("socket");
exit(-3);
}
int TRUE=1;
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &TRUE, sizeof(TRUE));
bind_addr.sin_family = AF_INET;
bind_addr.sin_port = htons( PORT_DNA );
bind_addr.sin_addr.s_addr = htonl( INADDR_ANY );
if(bind(sock,(struct sockaddr *)&bind_addr,sizeof(bind_addr))) {
fprintf(stderr,"MP HLR server could not bind to UDP port %d\n", PORT_DNA);
perror("bind");
exit(-3);
}
/* Detach from the console */
if (!foregroundMode) daemon(0,0);
while(1) {
unsigned char buffer[16384];
socklen_t recvaddrlen=sizeof(recvaddr);
struct pollfd fds;
int len;
bzero((void *)&recvaddr,sizeof(recvaddr));
fds.fd=sock; fds.events=POLLIN;
/* Wait patiently for packets to arrive */
while (poll(&fds,1,1000)<1) sleep(0);
len=recvfrom(sock,buffer,sizeof(buffer),0,&recvaddr,&recvaddrlen);
client_port=((struct sockaddr_in*)&recvaddr)->sin_port;
client_addr=((struct sockaddr_in*)&recvaddr)->sin_addr;
if (debug) fprintf(stderr,"Received packet from %s (len=%d).\n",inet_ntoa(client_addr),len);
if (debug>1) dump("recvaddr",(unsigned char *)&recvaddr,recvaddrlen);
if (debug>3) dump("packet",(unsigned char *)buffer,len);
if (dropPacketP(len)) {
if (debug) fprintf(stderr,"Simulation mode: Dropped packet due to simulated link parameters.\n");
continue;
}
if (!packetOk(buffer,len,NULL)) process_packet(buffer,len,&recvaddr,recvaddrlen);
else {
if (debug) setReason("Ignoring invalid packet");
}
if (debug>1) fprintf(stderr,"Finished processing packet, waiting for next one.\n");
}
return 0;
}
int processRequest(unsigned char *packet,int len,
@ -493,3 +512,63 @@ int respondSimple(char *sid,int action,unsigned char *action_text,int action_len
return 0;
}
int createServerSocket()
{
struct sockaddr_in bind_addr;
sock=socket(PF_INET,SOCK_DGRAM,0);
if (sock<0) {
fprintf(stderr,"Could not create UDP socket.\n");
perror("socket");
exit(-3);
}
int TRUE=1;
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &TRUE, sizeof(TRUE));
bind_addr.sin_family = AF_INET;
bind_addr.sin_port = htons( PORT_DNA );
bind_addr.sin_addr.s_addr = htonl( INADDR_ANY );
if(bind(sock,(struct sockaddr *)&bind_addr,sizeof(bind_addr))) {
fprintf(stderr,"MP HLR server could not bind to UDP port %d\n", PORT_DNA);
perror("bind");
exit(-3);
}
return 0;
}
int simpleServerMode()
{
while(1) {
unsigned char buffer[16384];
socklen_t recvaddrlen=sizeof(recvaddr);
struct pollfd fds;
int len;
bzero((void *)&recvaddr,sizeof(recvaddr));
fds.fd=sock; fds.events=POLLIN;
/* Wait patiently for packets to arrive */
while (poll(&fds,1,1000)<1) sleep(0);
len=recvfrom(sock,buffer,sizeof(buffer),0,&recvaddr,&recvaddrlen);
client_port=((struct sockaddr_in*)&recvaddr)->sin_port;
client_addr=((struct sockaddr_in*)&recvaddr)->sin_addr;
if (debug) fprintf(stderr,"Received packet from %s (len=%d).\n",inet_ntoa(client_addr),len);
if (debug>1) dump("recvaddr",(unsigned char *)&recvaddr,recvaddrlen);
if (debug>3) dump("packet",(unsigned char *)buffer,len);
if (dropPacketP(len)) {
if (debug) fprintf(stderr,"Simulation mode: Dropped packet due to simulated link parameters.\n");
continue;
}
if (!packetOk(buffer,len,NULL)) process_packet(buffer,len,&recvaddr,recvaddrlen);
else {
if (debug) setReason("Ignoring invalid packet");
}
if (debug>1) fprintf(stderr,"Finished processing packet, waiting for next one.\n");
}
return 0;
}