...
|
...
|
@@ -37,13 +37,20 @@ typedef struct urusai {
|
37
|
37
|
client *clients;
|
38
|
38
|
} urusai;
|
39
|
39
|
|
|
40
|
+typedef enum seenaction {
|
|
41
|
+ seen_error=0,
|
|
42
|
+ seen_new,
|
|
43
|
+ seen_updated,
|
|
44
|
+ seen_nochange
|
|
45
|
+} seenaction;
|
|
46
|
+
|
40
|
47
|
static int signal_init(int signum, void (*fn)(int));
|
41
|
48
|
static void sigint(int signum);
|
42
|
49
|
volatile int sigint_flag=0;
|
43
|
50
|
|
44
|
51
|
urusai *urusai_init(void);
|
45
|
52
|
void urusai_free(urusai *u);
|
46
|
|
-client *urusai_clientseen(urusai *u, char *id, struct sockaddr_in *addr);
|
|
53
|
+client *urusai_clientseen(urusai *u, char *id, struct sockaddr_in *addr, seenaction *seen);
|
47
|
54
|
int urusai_clientdeleteold(urusai *u, int timeout);
|
48
|
55
|
client *urusai_clientget(urusai *u, char *id);
|
49
|
56
|
int urusai_send(urusai *u, char *outbuf, int outbuf_used, client *destclient);
|
...
|
...
|
@@ -62,6 +69,7 @@ main(int argc, char *argv[])
|
62
|
69
|
urusai *u;
|
63
|
70
|
client *origclient, *destclient;
|
64
|
71
|
char *serial,*origid,*destid,*cmd,*contents;
|
|
72
|
+ seenaction seen;
|
65
|
73
|
if((u=urusai_init())==NULL) {
|
66
|
74
|
printf("ERROR: Couldn'n get/bind socket or insufficient memory\n");
|
67
|
75
|
return(1);
|
...
|
...
|
@@ -69,15 +77,16 @@ main(int argc, char *argv[])
|
69
|
77
|
sigint_flag=0;
|
70
|
78
|
signal_init(SIGINT,sigint);
|
71
|
79
|
while(!sigint_flag) {
|
|
80
|
+ memset(&clientaddr,0,sizeof(clientaddr));
|
72
|
81
|
clientaddr_len=sizeof(clientaddr);
|
73
|
82
|
if((inbuf_used=recvfrom(u->fd,inbuf,sizeof(inbuf),0,(struct sockaddr *)&clientaddr,&clientaddr_len))==-1)
|
74
|
83
|
continue; /* interrupted by signal */
|
75
|
84
|
if(msg_parse(inbuf,inbuf_used,&serial,&origid,&destid,&cmd,&contents)!=0)
|
76
|
85
|
continue;
|
77
|
|
- if((origclient=urusai_clientseen(u,origid,&clientaddr))==NULL)
|
|
86
|
+ if((origclient=urusai_clientseen(u,origid,&clientaddr,&seen))==NULL)
|
78
|
87
|
continue;
|
79
|
88
|
if(strcmp(cmd,"ping")==0) {
|
80
|
|
- outbuf_used=msg_compose(outbuf, sizeof(outbuf), serial, NULL, origid,"pong",NULL);
|
|
89
|
+ outbuf_used=msg_compose(outbuf, sizeof(outbuf), serial, NULL, origid,"pong",(seen==seen_new)?"new":(seen==seen_updated)?"updated":(seen==seen_nochange)?"nochange":NULL);
|
81
|
90
|
urusai_send(u,outbuf,outbuf_used,origclient);
|
82
|
91
|
} else if(strcmp(cmd,"message")==0) {
|
83
|
92
|
if((destclient=urusai_clientget(u,destid))==NULL) {
|
...
|
...
|
@@ -154,12 +163,15 @@ urusai_free(urusai *u)
|
154
|
163
|
}
|
155
|
164
|
|
156
|
165
|
client *
|
157
|
|
-urusai_clientseen(urusai *u, char *id, struct sockaddr_in *addr)
|
|
166
|
+urusai_clientseen(urusai *u, char *id, struct sockaddr_in *addr,seenaction *seen)
|
158
|
167
|
{
|
159
|
168
|
int i,ifree;
|
160
|
169
|
client *c;
|
161
|
|
- if(u==NULL)
|
|
170
|
+ if(u==NULL || id==NULL || addr==NULL || seen==NULL) {
|
|
171
|
+ if(seen!=NULL)
|
|
172
|
+ *seen=seen_error;
|
162
|
173
|
return(NULL);
|
|
174
|
+ }
|
163
|
175
|
if(u->numclients==u->sizeclients) {
|
164
|
176
|
client *newc;
|
165
|
177
|
if((newc=realloc(u->clients,sizeof(client)*(u->sizeclients+CLIENTBLOCK)))==NULL)
|
...
|
...
|
@@ -176,13 +188,21 @@ urusai_clientseen(urusai *u, char *id, struct sockaddr_in *addr)
|
176
|
188
|
break;
|
177
|
189
|
}
|
178
|
190
|
if(i==u->sizeclients) {
|
179
|
|
- if(ifree==-1)
|
|
191
|
+ if(ifree==-1) {
|
|
192
|
+ *seen=seen_error;
|
180
|
193
|
return(NULL);
|
|
194
|
+ }
|
181
|
195
|
i=ifree;
|
182
|
196
|
c=u->clients+i;
|
183
|
197
|
strncpy(c->id,id,sizeof(c->id));
|
184
|
198
|
c->id[sizeof(c->id)-1]='\0';
|
185
|
|
- }
|
|
199
|
+ *seen=seen_new;
|
|
200
|
+ } else {
|
|
201
|
+ if(memcmp(&(c->addr),addr,sizeof(c->addr))==0)
|
|
202
|
+ *seen=seen_nochange;
|
|
203
|
+ else
|
|
204
|
+ *seen=seen_updated;
|
|
205
|
+ }
|
186
|
206
|
c->lastrecv=time(NULL);
|
187
|
207
|
memcpy(&(c->addr),addr,sizeof(c->addr));
|
188
|
208
|
return(c);
|