~ubuntu-branches/ubuntu/karmic/libgrapple/karmic

« back to all changes in this revision

Viewing changes to src/.#socket.c.1.33

  • Committer: Bazaar Package Importer
  • Author(s): Lukas Fittl
  • Date: 2007-01-28 22:29:04 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20070128222904-bid1uquufll00hrs
Tags: 0.9.1-0ubuntu1
* New upstream release.
* ABI changed, upstream forgot to change version
  - configure.in: Increment MICRO_VERSION
  - debian/control: Update package name

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
    Grapple - A fully featured network layer with a simple interface
3
 
    Copyright (C) 2006 Michael Simms
4
 
 
5
 
    This library is free software; you can redistribute it and/or
6
 
    modify it under the terms of the GNU Lesser General Public
7
 
    License as published by the Free Software Foundation; either
8
 
    version 2.1 of the License, or (at your option) any later version.
9
 
 
10
 
    This library is distributed in the hope that it will be useful,
11
 
    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 
    Lesser General Public License for more details.
14
 
 
15
 
    You should have received a copy of the GNU Lesser General Public
16
 
    License along with this library; if not, write to the Free Software
17
 
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 
 
19
 
    Michael Simms
20
 
    michael@linuxgamepublishing.com
21
 
*/
22
 
 
23
 
#include <stdio.h>
24
 
#include <stdlib.h>
25
 
#include <sys/types.h>
26
 
#include <sys/socket.h>
27
 
#include <sys/select.h>
28
 
#include <unistd.h>
29
 
#include <netinet/in.h>
30
 
#include <sys/un.h>
31
 
#include <string.h>
32
 
#include <ctype.h>
33
 
#include <arpa/inet.h>
34
 
#include <netdb.h>
35
 
#include <sys/ioctl.h>
36
 
#include <errno.h>
37
 
#include <time.h>
38
 
#include <linux/limits.h>
39
 
#ifdef SOCK_SSL
40
 
#include <openssl/ssl.h>
41
 
#endif
42
 
 
43
 
#ifndef MSG_DONTWAIT
44
 
#define MSG_DONTWAIT 0x40
45
 
#endif
46
 
 
47
 
#include "dynstring.h"
48
 
#include "socket.h"
49
 
 
50
 
extern int gethostname (char *, size_t);
51
 
 
52
 
static int socket_udp2way_connectmessage(socketbuf *);
53
 
static int socket_udp2way_listener_data_process(socketbuf *,
54
 
                                                struct sockaddr_in *,
55
 
                                                size_t,signed char *,int);
56
 
static int socket_udp2way_reader_data_process(socketbuf *sock,
57
 
                                              signed char *buf,int datalen);
58
 
 
59
 
#ifdef SOCK_SSL
60
 
 
61
 
//Handle the SSL errors
62
 
 
63
 
static int ssl_process_error(SSL *ssl,int rv)
64
 
{
65
 
  switch (SSL_get_error(ssl,rv))
66
 
    {
67
 
    case SSL_ERROR_NONE:
68
 
    case SSL_ERROR_WANT_READ:
69
 
    case SSL_ERROR_WANT_WRITE:
70
 
    case SSL_ERROR_WANT_CONNECT:
71
 
    case SSL_ERROR_WANT_ACCEPT:
72
 
      rv=0;      //Set rv (the retutn value) to 0 for each of these errors
73
 
      break;
74
 
    case SSL_ERROR_ZERO_RETURN:
75
 
    case SSL_ERROR_WANT_X509_LOOKUP:
76
 
    case SSL_ERROR_SYSCALL:
77
 
    case SSL_ERROR_SSL:
78
 
      break;
79
 
    }
80
 
  return rv;
81
 
}
82
 
 
83
 
//Function to initialise the socket to be encrypted
84
 
static void socket_set_listener_encrypted(socketbuf *sock)
85
 
{
86
 
  int rv;
87
 
 
88
 
  SSL_METHOD *ssl_meth=0;
89
 
 
90
 
  ssl_meth=SSLv23_server_method();
91
 
 
92
 
  sock->ctx = SSL_CTX_new(ssl_meth);
93
 
  if (!sock->ctx)
94
 
    {
95
 
      sock->encrypted=0;
96
 
      sock->flags |= SOCKET_DEAD;
97
 
      return;
98
 
    }
99
 
 
100
 
  if (!sock->server_cert_file || !*sock->server_cert_file ||
101
 
      !sock->server_key_file || !*sock->server_key_file)
102
 
    {
103
 
      sock->encrypted=0;
104
 
      sock->flags |= SOCKET_DEAD;
105
 
      return;
106
 
    }
107
 
 
108
 
  rv=SSL_CTX_use_certificate_file(sock->ctx,sock->server_cert_file,
109
 
                                  SSL_FILETYPE_PEM);
110
 
 
111
 
  rv=SSL_CTX_use_RSAPrivateKey_file(sock->ctx,sock->server_key_file,
112
 
                                    SSL_FILETYPE_PEM);
113
 
 
114
 
  if (!SSL_CTX_check_private_key(sock->ctx)) 
115
 
    {
116
 
      printf("Private key does not match the certificate public key\n");
117
 
      sock->encrypted=0;
118
 
      sock->flags |= SOCKET_DEAD;
119
 
      return;
120
 
    }
121
 
 
122
 
  //It has all initialised correctly, set it as encrypted
123
 
  sock->encrypted=1;
124
 
}
125
 
 
126
 
//Set the socket to be a host type encrypted socket - so other sockets will
127
 
//verify against it.
128
 
static void socket_set_server_encrypted(socketbuf *sock)
129
 
{
130
 
  int rv;
131
 
 
132
 
  if (sock->encrypted==2)
133
 
    {
134
 
      sock->ctx = sock->parent->ctx;
135
 
      if (!sock->ctx)
136
 
        {
137
 
          sock->encrypted=0;
138
 
          sock->flags |= SOCKET_DEAD;
139
 
          return;
140
 
        }
141
 
 
142
 
      sock->ssl = SSL_new(sock->ctx);
143
 
      if (!sock->ssl)
144
 
        {
145
 
          SSL_CTX_free(sock->ctx);
146
 
          sock->ctx=0;
147
 
          sock->encrypted=0;
148
 
          sock->flags |= SOCKET_DEAD;
149
 
a         return;
150
 
        }
151
 
 
152
 
      SSL_set_fd(sock->ssl,sock->fd);
153
 
 
154
 
      sock->encrypted=3;
155
 
    }
156
 
  
157
 
  if (sock->encrypted==3)
158
 
    {
159
 
      rv=SSL_accept(sock->ssl);
160
 
 
161
 
      if (rv<0)
162
 
        {
163
 
          rv=ssl_process_error(sock->ssl,rv);
164
 
        }
165
 
 
166
 
      if (rv<0)
167
 
        {
168
 
          SSL_CTX_free(sock->ctx);
169
 
          sock->ctx=0;
170
 
          
171
 
          SSL_free(sock->ssl);
172
 
          sock->ssl=0;
173
 
 
174
 
          sock->encrypted=0;
175
 
          sock->flags |= SOCKET_DEAD;
176
 
          return;
177
 
        }
178
 
 
179
 
      if (rv==0)
180
 
        return;
181
 
 
182
 
      sock->encrypted=4;
183
 
    }
184
 
 
185
 
  if (sock->encrypted==4)
186
 
    {
187
 
      if (!strcmp(SSL_get_cipher(sock->ssl),"(NONE)"))
188
 
        {
189
 
          SSL_CTX_free(sock->ctx);
190
 
          sock->ctx=0;
191
 
          
192
 
          SSL_free(sock->ssl);
193
 
          sock->ssl=0;
194
 
 
195
 
          sock->encrypted=0;
196
 
          sock->flags |= SOCKET_DEAD;
197
 
          return;
198
 
        }
199
 
    }
200
 
 
201
 
  SSL_set_mode(sock->ssl,
202
 
               SSL_get_mode(sock->ssl)|SSL_MODE_ENABLE_PARTIAL_WRITE);
203
 
 
204
 
  //It worked, note it as an encrypted socket
205
 
  sock->encrypted=1;
206
 
 
207
 
  return;
208
 
}
209
 
 
210
 
//Set this socket up to be an encryption client that will verift against the
211
 
//host
212
 
static void socket_set_client_encrypted(socketbuf *sock)
213
 
{
214
 
  SSL_METHOD *ssl_meth=0;
215
 
  int rv;
216
 
 
217
 
  if (sock->encrypted==2)
218
 
    {
219
 
      ssl_meth=SSLv23_client_method();
220
 
 
221
 
      sock->ctx = SSL_CTX_new(ssl_meth);
222
 
      if (!sock->ctx)
223
 
        {
224
 
          sock->encrypted=0;
225
 
          sock->flags |= SOCKET_DEAD;
226
 
          return;
227
 
        }
228
 
 
229
 
      sock->ssl=SSL_new(sock->ctx);
230
 
      if (!sock->ssl)
231
 
        {
232
 
          SSL_CTX_free(sock->ctx);
233
 
          sock->ctx=0;
234
 
          sock->encrypted=0;
235
 
          sock->flags |= SOCKET_DEAD;
236
 
          return;
237
 
        }
238
 
 
239
 
      if (sock->client_ca_file)
240
 
        {
241
 
          rv=SSL_CTX_load_verify_locations(sock->ctx,sock->client_ca_file,NULL);
242
 
          
243
 
          if (!rv)
244
 
            {
245
 
              SSL_CTX_free(sock->ctx);
246
 
              sock->ctx=0;
247
 
              sock->encrypted=0;
248
 
              sock->flags |= SOCKET_DEAD;
249
 
              return;
250
 
            }
251
 
        }
252
 
      
253
 
      SSL_set_fd(sock->ssl,sock->fd);
254
 
 
255
 
      sock->encrypted=3;
256
 
    }
257
 
  
258
 
  if (sock->encrypted==3)
259
 
    {
260
 
      rv=SSL_connect(sock->ssl);
261
 
 
262
 
      if (rv<0)
263
 
        {
264
 
          rv=ssl_process_error(sock->ssl,rv);
265
 
        }
266
 
 
267
 
      if (rv<0)
268
 
        {
269
 
          SSL_CTX_free(sock->ctx);
270
 
          sock->ctx=0;
271
 
          
272
 
          SSL_free(sock->ssl);
273
 
          sock->ssl=0;
274
 
 
275
 
          sock->encrypted=0;
276
 
          sock->flags |= SOCKET_DEAD;
277
 
          return;
278
 
        }
279
 
 
280
 
      if (rv==0)
281
 
        return;
282
 
 
283
 
      sock->encrypted=4;
284
 
    }
285
 
 
286
 
  if (sock->encrypted==4)
287
 
    {
288
 
      if (!strcmp(SSL_get_cipher(sock->ssl),"(NONE)"))
289
 
        {
290
 
          SSL_CTX_free(sock->ctx);
291
 
          sock->ctx=0;
292
 
          
293
 
          SSL_free(sock->ssl);
294
 
          sock->ssl=0;
295
 
 
296
 
          sock->encrypted=0;
297
 
          sock->flags |= SOCKET_DEAD;
298
 
          return;
299
 
        }
300
 
    }
301
 
 
302
 
  if (sock->client_ca_file)
303
 
    {
304
 
      //Now we verify that the cert we have is good
305
 
      rv=SSL_get_verify_result(sock->ssl);
306
 
 
307
 
      if (rv!=X509_V_OK)
308
 
        {
309
 
          SSL_CTX_free(sock->ctx);
310
 
          sock->ctx=0;
311
 
          
312
 
          SSL_free(sock->ssl);
313
 
          sock->ssl=0;
314
 
 
315
 
          sock->encrypted=0;
316
 
          sock->flags |= SOCKET_DEAD;
317
 
 
318
 
          return;
319
 
        }
320
 
    }
321
 
 
322
 
  SSL_set_mode(sock->ssl,
323
 
               SSL_get_mode(sock->ssl)|SSL_MODE_ENABLE_PARTIAL_WRITE);
324
 
 
325
 
  //Successful
326
 
  sock->encrypted=1;
327
 
 
328
 
  return;
329
 
}
330
 
 
331
 
static void socket_process_ssl(socketbuf *sock)
332
 
{
333
 
  if (sock->flags & SOCKET_INCOMING)
334
 
    socket_set_server_encrypted(sock);
335
 
  else
336
 
    socket_set_client_encrypted(sock);
337
 
}  
338
 
#endif //SOCK_SSL
339
 
 
340
 
#ifdef DEBUG
341
 
//Simple debug function that reports all socket data to a file, the filename
342
 
//based on the fd number
343
 
static void socket_data_debug(socketbuf *sock,char *buf,int len,int writer)
344
 
{
345
 
  FILE *fp;
346
 
  int loopa;
347
 
  char filename[PATH_MAX];
348
 
 
349
 
  //Set the filename  
350
 
  if (writer)
351
 
    sprintf(filename,"/tmp/socket_%d.write",sock->fd);
352
 
  else
353
 
    sprintf(filename,"/tmp/socket_%d.read",sock->fd);
354
 
 
355
 
  //Open the file for appending
356
 
  fp=fopen(filename,"a");
357
 
  if (fp)
358
 
    {
359
 
      //Write the bytes into the file, on oneline. If the value is printable
360
 
      //also write the character, as this can help debugging some streams
361
 
      for (loopa=0;loopa<len;loopa++)
362
 
        {
363
 
          if (isprint(buf[loopa]))
364
 
            fprintf(fp,"%d(%c) ",buf[loopa],buf[loopa]);
365
 
          else
366
 
            fprintf(fp,"%d ",buf[loopa]);
367
 
        }
368
 
 
369
 
      //Finish off with a newline
370
 
      fprintf(fp,"\n");
371
 
 
372
 
      //Close the file, we're done
373
 
      fclose(fp);
374
 
    }
375
 
  return;
376
 
}
377
 
#endif
378
 
 
379
 
//Generic function to write data to the socket. This is called from
380
 
//outside. We do NOT actually write the data to the socket at this stage, we
381
 
//just add it to a buffer
382
 
void socket_write(socketbuf *sock,
383
 
                  const char *data,size_t len)
384
 
{
385
 
  socket_intchar udplen,udpdata;
386
 
  int newlen;
387
 
 
388
 
  //If we are using UDP we need to do it differently, as UDP sends discrete 
389
 
  //packets not a stream
390
 
  if (sock->protocol==SOCKET_UDP)
391
 
    {
392
 
      //Calculate how long the length will be of the UDP packet
393
 
      newlen=len;
394
 
      if (sock->udp2w)
395
 
        {
396
 
          //It will be 4 extra bytes if it is a 2 way UDP
397
 
 
398
 
          if (sock->udp2w_infd)
399
 
            //And an extra 4 if we have the incoming socket ready
400
 
            newlen+=8;
401
 
          else
402
 
            //Just that 4
403
 
            newlen+=4;
404
 
        }
405
 
 
406
 
      //So, the first data goes in, this is the length of the following data
407
 
      //This happens for all UDP packets, so the buffer knows how long to send
408
 
      //as the data packet
409
 
      udplen.i=newlen;
410
 
      dynstringRawappend(sock->outdata,udplen.c,4);
411
 
 
412
 
      if (sock->udp2w)
413
 
        {
414
 
          //Then for 2 way UDP, we send the protocol - we are sending user
415
 
          //data not a low level protocol packet
416
 
          udpdata.i=htonl(SOCKET_UDP2W_PROTOCOL_DATA);
417
 
          dynstringRawappend(sock->outdata,udpdata.c,4);
418
 
          if (sock->udp2w_infd)
419
 
            {
420
 
              //We then send the port number of the return port, if we have one
421
 
              udpdata.i=htonl(sock->udp2w_port);
422
 
              dynstringRawappend(sock->outdata,udpdata.c,4);
423
 
            }
424
 
        }
425
 
    }
426
 
 
427
 
 
428
 
  //Now we simply append the data itself. If this is TCP thats all we need
429
 
  //to do, as TCP sends a whole stream, its up to the client to rebuild
430
 
  //it, with UDP we have made and sent a header
431
 
  dynstringRawappend(sock->outdata,data,len);
432
 
  sock->bytes_out+=len;
433
 
 
434
 
  return;
435
 
}
436
 
 
437
 
//rdata is the resend data, used on reliable UDP packets to resend
438
 
//packets that may have gone missing. Here we delete one from a
439
 
//linked list. Any linked list, we dont care
440
 
static socket_udp_rdata *socket_rdata_delete(socket_udp_rdata *list,
441
 
                                             socket_udp_rdata *target)
442
 
{
443
 
  if (target->next==target)
444
 
    {
445
 
      list=NULL;
446
 
    }
447
 
  else
448
 
    {
449
 
      target->next->prev=target->prev;
450
 
      target->prev->next=target->next;
451
 
      if (target==list)
452
 
        list=target->next;
453
 
    }
454
 
 
455
 
  if (target->data)
456
 
    free(target->data);
457
 
  free(target);
458
 
  
459
 
  return list;
460
 
}
461
 
 
462
 
//This function locates a rdata packet by its ID from a list
463
 
static socket_udp_rdata *socket_rdata_locate_packetnum(socket_udp_rdata *list,
464
 
                                                       int packetnum)
465
 
{
466
 
  socket_udp_rdata *scan;
467
 
 
468
 
  scan=list;
469
 
 
470
 
  //Scan through the list
471
 
  while (scan)
472
 
    {
473
 
      if (scan->packetnum==packetnum)
474
 
        //We have a match, return it
475
 
        return scan;
476
 
 
477
 
      scan=scan->next;
478
 
      if (scan==list)
479
 
        //Come to the end of the list (it is circular)
480
 
        scan=NULL;
481
 
    }
482
 
  
483
 
  //No match, return NULL
484
 
  return NULL;
485
 
}
486
 
 
487
 
//Allocate an rdata packet and put it into a list
488
 
static socket_udp_rdata *rdata_allocate(socket_udp_rdata *list,
489
 
                                        int packetnum,
490
 
                                        const char *data,int len,int sent)
491
 
{
492
 
  socket_udp_rdata *newpacket;
493
 
 
494
 
  //Allocate the memory
495
 
  newpacket=(socket_udp_rdata *)calloc(1,sizeof(socket_udp_rdata));
496
 
 
497
 
  //Allocate the data segment memory
498
 
  newpacket->data=(char *)malloc(len);
499
 
  memcpy(newpacket->data,data,len);
500
 
  
501
 
  newpacket->length=len;
502
 
  newpacket->sent=sent;
503
 
 
504
 
  //Set the send time
505
 
  gettimeofday(&newpacket->sendtime,NULL);
506
 
  
507
 
  newpacket->packetnum=packetnum;
508
 
 
509
 
  //Link this into the list we have supplied
510
 
  if (list)
511
 
    {
512
 
      newpacket->next=list;
513
 
      newpacket->prev=list->prev;
514
 
      newpacket->prev->next=newpacket;
515
 
      newpacket->next->prev=newpacket;
516
 
      
517
 
      return list;
518
 
    }
519
 
 
520
 
  newpacket->next=newpacket;
521
 
  newpacket->prev=newpacket;
522
 
 
523
 
  return newpacket;
524
 
}
525
 
 
526
 
 
527
 
//Write a data packet in reliable mode
528
 
void socket_write_reliable(socketbuf *sock,
529
 
                           const char *data,size_t len)
530
 
{
531
 
  socket_intchar udplen,udpdata;
532
 
  int newlen,packetnum;
533
 
 
534
 
  //If we arent using 2 way UDP, we just send, as we cant have reliable one way
535
 
  //UDP and UDP is the only protocol we support that is unreliable
536
 
  if (sock->protocol!=SOCKET_UDP || !sock->udp2w)
537
 
    {
538
 
      socket_write(sock,
539
 
                   data,len);
540
 
      return;
541
 
    }
542
 
 
543
 
  //Incriment the outbound packet number
544
 
  packetnum=sock->udp2w_routpacket++;
545
 
 
546
 
  //Calculate the length of the data
547
 
  newlen=len;
548
 
  if (sock->udp2w_infd)
549
 
    newlen+=12;
550
 
  else
551
 
    newlen+=8;
552
 
 
553
 
  //Send the length first //This does NOT get htonl'd as it gets stripped
554
 
  //before actually sending it
555
 
  udplen.i=newlen;
556
 
  dynstringRawappend(sock->outdata,udplen.c,4);
557
 
 
558
 
  //Then the protocol
559
 
  udpdata.i=htonl(SOCKET_UDP2W_PROTOCOL_RDATA);
560
 
 
561
 
  dynstringRawappend(sock->outdata,udpdata.c,4);
562
 
 
563
 
  if (sock->udp2w_infd)
564
 
    {
565
 
      //Then the port number
566
 
      udpdata.i=htonl(sock->udp2w_port);
567
 
      dynstringRawappend(sock->outdata,udpdata.c,4);
568
 
    }
569
 
 
570
 
  //Then the packet number, so the other end keeps in sync
571
 
  udpdata.i=htonl(packetnum);
572
 
  dynstringRawappend(sock->outdata,udpdata.c,4);
573
 
 
574
 
  //Then the data itself
575
 
  dynstringRawappend(sock->outdata,data,len);
576
 
  sock->bytes_out+=len;
577
 
 
578
 
  //Add this packet to the RDATA out list, so we know to resend it if we
579
 
  //dont get a confirmation of the receipt
580
 
  sock->udp2w_rdata_out=rdata_allocate(sock->udp2w_rdata_out,
581
 
                                       packetnum,
582
 
                                       data,len,0);
583
 
 
584
 
  return;
585
 
}
586
 
 
587
 
//Just a user accessible function to return the number of bytes received
588
 
size_t socket_bytes_in(socketbuf *sock)
589
 
{
590
 
  return sock->bytes_in;
591
 
}
592
 
 
593
 
//Just a user accessible function to return the number of bytes sent
594
 
size_t socket_bytes_out(socketbuf *sock)
595
 
{
596
 
  return sock->bytes_out;
597
 
}
598
 
 
599
 
//Sockets are processed out of a 'processlist' - which is a linked list
600
 
//of socketbuf's. This function adds a socketbuf to a processlist. It creates
601
 
//a processlist object to hold the socketbuf
602
 
socket_processlist *socket_link(socket_processlist *list,socketbuf *sock)
603
 
{
604
 
  socket_processlist *newitem;
605
 
  newitem=(socket_processlist *)malloc(sizeof(socket_processlist));
606
 
  newitem->sock=sock;
607
 
 
608
 
  if (!list)
609
 
    {
610
 
      newitem->next=newitem;
611
 
      newitem->prev=newitem;
612
 
 
613
 
      return newitem;
614
 
    }
615
 
 
616
 
  newitem->next=list;
617
 
  newitem->prev=list->prev;
618
 
 
619
 
  newitem->next->prev=newitem;
620
 
  newitem->prev->next=newitem;
621
 
  
622
 
  return list;
623
 
}
624
 
 
625
 
//And this function unlinks a socketbuf from a processlist. It also frees the
626
 
//processlist container that held the socketbuf
627
 
socket_processlist *socket_unlink(socket_processlist *list,socketbuf *sock)
628
 
{
629
 
  socket_processlist *scan;
630
 
 
631
 
  if (list->next==list)
632
 
    {
633
 
      if (list->sock!=sock)
634
 
        return list;
635
 
 
636
 
      free(list);
637
 
      return NULL;
638
 
    }
639
 
  
640
 
  scan=list;
641
 
 
642
 
  while (scan)
643
 
    {
644
 
      if (scan->sock==sock)
645
 
        {
646
 
          scan->prev->next=scan->next;
647
 
          scan->next->prev=scan->prev;
648
 
          if (scan==list)
649
 
            list=scan->next;
650
 
          free(scan);
651
 
          return list;
652
 
        }
653
 
      scan=scan->next;
654
 
      if (scan==list)
655
 
        return list;
656
 
    }
657
 
 
658
 
  return list;
659
 
}
660
 
 
661
 
//This is the basic function for creating a socketbuf object around a
662
 
//file descriptor
663
 
static socketbuf *socket_create(int fd)
664
 
{
665
 
  socketbuf *returnval;
666
 
 
667
 
  //Allocate the memory for the socket
668
 
  returnval=(socketbuf *)calloc(1,sizeof(socketbuf));
669
 
 
670
 
  //Give it a small in and out buffer - these resize dynamically so it doesnt
671
 
  //really matter what size we give it. 128 is a fairly small number in case
672
 
  //the socket only sends small bits of data, this saves over-allocating.
673
 
  returnval->indata=dynstringInit(128);
674
 
  returnval->outdata=dynstringInit(128);
675
 
 
676
 
  //Set the file descriptor into the structure
677
 
  returnval->fd=fd;
678
 
 
679
 
  //Thats it, we have our socketbuf. Much more wil happen to this depending
680
 
  //on what the type of socket being made is, this data will be filled in
681
 
  //by the function that calls this one.
682
 
  return returnval;
683
 
}
684
 
 
685
 
//We are destroying a socket. We are also however needing to be careful that
686
 
//we destroy any connecting sockets if this is a listener.
687
 
void socket_destroy(socketbuf *sock)
688
 
{
689
 
  socketbuf *scan;
690
 
 
691
 
  while (sock->new_children)
692
 
    {
693
 
      //Now we MUST destroy this, they are connecting sockets who have
694
 
      //no parent, if we dont destroy now we will leak memory
695
 
      //This will, incidentally, cascade down, destroying always the last
696
 
      //one in the tree, and then roll back up to here
697
 
      socket_destroy(sock->new_children);
698
 
    }
699
 
 
700
 
  //Here we must now also disconnect all connected children. These have been
701
 
  //accessed by the parent program and so it is not our responsibility to
702
 
  //keep track of them. Why did we keep them in a list in the first place?
703
 
  //Well, things like UDP, all data comes in on the listener, not on a
704
 
  //socket dedicated to the other end, so we need to have a list of all
705
 
  //who have connected, so we know who to send the data to/
706
 
  scan=sock->connected_children;
707
 
  while (scan)
708
 
    {
709
 
      if (scan->parent==sock)
710
 
        scan->parent=NULL;
711
 
      
712
 
      scan=scan->connected_child_next;
713
 
      if (scan==sock->connected_children)
714
 
        scan=NULL;
715
 
    }
716
 
 
717
 
  //If we have a parent, then unlink ourselves from the parent, so that
718
 
  //this socket is no longer in contention for any data received by the
719
 
  //parent socket, if it is UDP
720
 
  if (sock->parent)
721
 
    {
722
 
      if (sock->new_child_next)
723
 
        {
724
 
          if (sock->parent->new_children==sock)
725
 
            sock->parent->new_children=sock->new_child_next;
726
 
          if (sock->parent->new_children==sock)
727
 
            sock->parent->new_children=NULL;
728
 
        }
729
 
      
730
 
      if (sock->connected_child_next)
731
 
        {
732
 
          if (sock->parent->connected_children==sock)
733
 
            sock->parent->connected_children=sock->connected_child_next;
734
 
          if (sock->parent->connected_children==sock)
735
 
            sock->parent->connected_children=NULL;
736
 
        }
737
 
    }
738
 
 
739
 
  //Unlink ourselves from the list of sockets connected to the same
740
 
  //parent, which can be intact even if the parent is gone.
741
 
  if (sock->new_child_next)
742
 
    {
743
 
      sock->new_child_next->new_child_prev=sock->new_child_prev;
744
 
      sock->new_child_prev->new_child_next=sock->new_child_next;
745
 
    }
746
 
  
747
 
  if (sock->connected_child_next)
748
 
    {
749
 
      sock->connected_child_next->connected_child_prev=sock->connected_child_prev;
750
 
      sock->connected_child_prev->connected_child_next=sock->connected_child_next;
751
 
    }
752
 
 
753
 
  //Finally we have done the internal management, we need to actually
754
 
  //destroy the socket!
755
 
  if (sock->fd)
756
 
    {
757
 
      //If we have the socket, kill it
758
 
 
759
 
      if (sock->flags & SOCKET_CONNECTED)
760
 
        //shutdown, if its connected
761
 
        shutdown(sock->fd,0);
762
 
 
763
 
      //Then close the socket
764
 
      close(sock->fd);
765
 
    }
766
 
  //The data socket itself is now disconnected.
767
 
 
768
 
  //On a 2 way UDP, we need to also close the other socket
769
 
  if (sock->udp2w_infd)
770
 
    {
771
 
      //If we have the socket, kill it
772
 
 
773
 
      //shutdown, if its connected
774
 
      shutdown(sock->udp2w_infd,0);
775
 
 
776
 
      //Then close the socket
777
 
      close(sock->udp2w_infd);
778
 
    }
779
 
  //The udp2w_infd socket itself is now disconnected.
780
 
 
781
 
  //On an interrupt docket we have a different one
782
 
  if (sock->interrupt_fd)
783
 
    {
784
 
      //If we have the socket, kill it
785
 
 
786
 
      //shutdown, if its connected
787
 
      shutdown(sock->interrupt_fd,0);
788
 
 
789
 
      //Then close the socket
790
 
      close(sock->interrupt_fd);
791
 
    }
792
 
  
793
 
  //Free the memory used in the transmit and receive queues
794
 
  if (sock->indata)
795
 
    dynstringUninit(sock->indata);
796
 
 
797
 
  if (sock->outdata)
798
 
    dynstringUninit(sock->outdata);
799
 
 
800
 
  //Free the resend data queues, we dont need them any more, any data that
801
 
  //still hasnt made it isnt going to now.
802
 
  while (sock->udp2w_rdata_out)
803
 
    sock->udp2w_rdata_out=socket_rdata_delete(sock->udp2w_rdata_out,
804
 
                                              sock->udp2w_rdata_out);
805
 
  while (sock->udp2w_rdata_in)
806
 
    sock->udp2w_rdata_in=socket_rdata_delete(sock->udp2w_rdata_in,
807
 
                                             sock->udp2w_rdata_in);
808
 
 
809
 
  //Free the hostname
810
 
  if (sock->host)
811
 
    free(sock->host);
812
 
 
813
 
  //Free the pathname (applies to unix sockets only)
814
 
  if (sock->path)
815
 
    {
816
 
      if (sock->flags & SOCKET_LISTENER)
817
 
        unlink(sock->path);
818
 
      free(sock->path);
819
 
    }
820
 
 
821
 
  //Free the socket data, we are done
822
 
  free(sock);
823
 
 
824
 
  return;
825
 
}
826
 
 
827
 
//Create the listener socket for a unix connection
828
 
socketbuf *socket_create_unix_wait(const char *path,int wait)
829
 
{
830
 
  int fd;
831
 
  socketbuf *returnval;
832
 
  struct sockaddr_un sa;
833
 
  int dummy,selectnum;
834
 
  fd_set writer;
835
 
#ifndef FIONBIO
836
 
# ifdef O_NONBLOCK
837
 
  int flags;
838
 
# endif
839
 
#endif
840
 
 
841
 
  //We must specify a path in the filesystem, that is where the socket lives.
842
 
  //Without it, no way to create it.
843
 
  if (!path || !*path)
844
 
    return 0;
845
 
 
846
 
  //create the sockets file descriptor
847
 
  fd=socket(PF_UNIX,SOCK_STREAM,0);
848
 
 
849
 
  if (fd<1)
850
 
    {
851
 
      //Socket creation failed.
852
 
      return 0;
853
 
    }
854
 
 
855
 
  memset(&sa,0,sizeof(struct sockaddr_in));
856
 
 
857
 
  //Set the fd as a UNIX socket
858
 
  sa.sun_family = AF_UNIX;
859
 
  strcpy(sa.sun_path,path);
860
 
 
861
 
  //Set non-blocking, so we can check for a data without freezing. If we
862
 
  //fail to set non-blocking we must abort, we require it.
863
 
#ifdef FIONBIO
864
 
  dummy=1;
865
 
 
866
 
  if (ioctl(fd,FIONBIO,&dummy)<0)
867
 
    {
868
 
      close(fd);
869
 
      return 0;
870
 
    }
871
 
#else
872
 
# ifdef O_NONBLOCK
873
 
  flags=fcntl(fd,F_GETFL,0);
874
 
 
875
 
  if (flags<0)
876
 
    {
877
 
      close(fd);
878
 
      return 0;
879
 
    }
880
 
 
881
 
  if (fcntl(fd,F_SETFL,flags|O_NONBLOCK)<0)
882
 
    {
883
 
      close(fd);
884
 
      return 0;
885
 
    }
886
 
 
887
 
# else
888
 
#  error No valid non-blocking method - cannot build;
889
 
# endif // O_NONBLOCK
890
 
#endif //FIONBIO
891
 
 
892
 
 
893
 
  //We have the good file descriptor, set it into a socketbuf structure
894
 
  returnval=socket_create(fd);
895
 
 
896
 
  //Note the protocol
897
 
  returnval->protocol=SOCKET_UNIX;
898
 
 
899
 
  //And store the path
900
 
  returnval->path=(char *)malloc(strlen(path)+1);
901
 
  strcpy(returnval->path,path);
902
 
 
903
 
  //Up to now this has all been preparation, now we actually connect to the
904
 
  //socket
905
 
  if (connect(fd,(struct sockaddr *)&sa,sizeof(sa))==0)
906
 
    {
907
 
      //Connect was successful, we can finish this here
908
 
      returnval->flags |= SOCKET_CONNECTED;
909
 
      returnval->connect_time=time(NULL);
910
 
 
911
 
      return returnval;
912
 
    }
913
 
  
914
 
  //The connection is 'in progress'
915
 
  if (errno==EINPROGRESS)
916
 
    {
917
 
      //Connect was possibly OK, but we havent finished, come back
918
 
      //and check later with select
919
 
      returnval->flags|=SOCKET_CONNECTING;
920
 
 
921
 
      if (!wait)
922
 
        {
923
 
          //We were called with the option NOT to wait for it to connect, so
924
 
          //we return here. It is now the responsibility of the caller to
925
 
          //process this socket occasionally and see if it has now connected
926
 
          //or if the connection failed.
927
 
 
928
 
          return returnval;
929
 
        }
930
 
      else
931
 
        {
932
 
          //We were asked to keep waiting for the socket to connect
933
 
          while (returnval->flags & SOCKET_CONNECTING)
934
 
            {
935
 
              //To test if we have connected yet, we select on the socket,
936
 
              //to see if its writer returns
937
 
              FD_ZERO(&writer);
938
 
              FD_SET(returnval->fd,&writer);
939
 
 
940
 
              //We need to wait, as long as it takes, so we set no timeout
941
 
              selectnum=select(FD_SETSIZE,0,&writer,0,NULL);
942
 
 
943
 
              //The select failed, this means an error, we couldnt connect
944
 
              if (selectnum<0)
945
 
                {
946
 
                  socket_destroy(returnval);
947
 
 
948
 
                  return 0;
949
 
                }
950
 
              if (selectnum>0)
951
 
                {
952
 
                  //At least one socket (it has to be us) returned data
953
 
                  if (FD_ISSET(returnval->fd,&writer))
954
 
                    {
955
 
 
956
 
                      //We have connected
957
 
                      returnval->flags &=~ SOCKET_CONNECTING;
958
 
                      returnval->flags |= SOCKET_CONNECTED;
959
 
                      returnval->connect_time=time(NULL);
960
 
                      return returnval;
961
 
                    }
962
 
                }
963
 
            }
964
 
        }
965
 
    }
966
 
 
967
 
  //It was an error, and a bad one, close this
968
 
  socket_destroy(returnval);
969
 
 
970
 
  return 0;
971
 
}
972
 
 
973
 
//Create a wakeup socket
974
 
socketbuf *socket_create_interrupt(void)
975
 
{
976
 
  int fd[2];
977
 
  socketbuf *returnval;
978
 
  int dummy;
979
 
#ifndef FIONBIO
980
 
# ifdef O_NONBLOCK
981
 
  int flags;
982
 
# endif
983
 
#endif
984
 
 
985
 
  //create the sockets file descriptor
986
 
  if (pipe(fd)==-1)
987
 
    return 0;
988
 
 
989
 
  //Set non-blocking, so we can check for a data without freezing. If we
990
 
  //fail to set non-blocking we must abort, we require it.
991
 
#ifdef FIONBIO
992
 
  dummy=1;
993
 
 
994
 
  if (ioctl(fd[0],FIONBIO,&dummy)<0)
995
 
    {
996
 
      close(fd[0]);
997
 
      close(fd[1]);
998
 
      return 0;
999
 
    }
1000
 
 
1001
 
  dummy=1;
1002
 
 
1003
 
  if (ioctl(fd[1],FIONBIO,&dummy)<0)
1004
 
    {
1005
 
      close(fd[0]);
1006
 
      close(fd[1]);
1007
 
      return 0;
1008
 
    }
1009
 
#else
1010
 
# ifdef O_NONBLOCK
1011
 
 
1012
 
  flags=fcntl(fd[0],F_GETFL,0);
1013
 
 
1014
 
  if (flags[0]<0)
1015
 
    {
1016
 
      close(fd[0]);
1017
 
      close(fd[1]);
1018
 
      return 0;
1019
 
    }
1020
 
 
1021
 
  if (fcntl(fd[0],F_SETFL,flags|O_NONBLOCK)<0)
1022
 
    {
1023
 
      close(fd[0]);
1024
 
      close(fd[1]);
1025
 
      return 0;
1026
 
    }
1027
 
 
1028
 
  flags=fcntl(fd[1],F_GETFL,0);
1029
 
 
1030
 
  if (flags[1]<0)
1031
 
    {
1032
 
      close(fd[0]);
1033
 
      close(fd[1]);
1034
 
      return 0;
1035
 
    }
1036
 
 
1037
 
  if (fcntl(fd[1],F_SETFL,flags|O_NONBLOCK)<0)
1038
 
    {
1039
 
      close(fd[0]);
1040
 
      close(fd[1]);
1041
 
      return 0;
1042
 
    }
1043
 
 
1044
 
# else
1045
 
#  error No valid non-blocking method - cannot build;
1046
 
# endif // O_NONBLOCK
1047
 
#endif //FIONBIO
1048
 
 
1049
 
 
1050
 
  //We have the good file descriptor, set it into a socketbuf structure
1051
 
  returnval=socket_create(fd[0]);
1052
 
  returnval->interrupt_fd=fd[1];
1053
 
 
1054
 
  //Note the protocol
1055
 
  returnval->protocol=SOCKET_INTERRUPT;
1056
 
 
1057
 
  returnval->flags |= SOCKET_CONNECTED;
1058
 
 
1059
 
  returnval->connect_time=time(NULL);
1060
 
 
1061
 
  return returnval;
1062
 
}
1063
 
 
1064
 
int socket_interrupt(socketbuf *sock)
1065
 
{
1066
 
  if (sock && sock->protocol==SOCKET_INTERRUPT)
1067
 
    {
1068
 
      write(sock->interrupt_fd,"0",1);
1069
 
      sock->bytes_out++;
1070
 
    }
1071
 
 
1072
 
  return 0;
1073
 
}
1074
 
 
1075
 
//Create a TCPIP connection to a remote socket
1076
 
socketbuf *socket_create_inet_tcp_wait(const char *host,int port,int wait)
1077
 
{
1078
 
  int fd;
1079
 
  socketbuf *returnval;
1080
 
  struct sockaddr_in sa;
1081
 
  int dummy,selectnum;
1082
 
  struct in_addr inet_address;
1083
 
  struct hostent *hp;
1084
 
  fd_set writer;
1085
 
  struct sockaddr_in peername;
1086
 
  socklen_t peersize;
1087
 
#ifndef FIONBIO
1088
 
# ifdef O_NONBLOCK
1089
 
  int flags;
1090
 
# endif
1091
 
#endif
1092
 
 
1093
 
  //We need the hostname, where will we connect without one
1094
 
  if (!host || !*host)
1095
 
    return 0;
1096
 
 
1097
 
  //Create the socket
1098
 
  fd=socket(AF_INET,SOCK_STREAM,0);
1099
 
 
1100
 
  if (fd<1)
1101
 
    {
1102
 
      //Basic socket connection failed, this really shouldnt happen
1103
 
      return 0;
1104
 
    }
1105
 
 
1106
 
  memset(&sa,0,sizeof(struct sockaddr_in));
1107
 
 
1108
 
  //Find the hostname
1109
 
  hp=gethostbyname(host);
1110
 
  if (!hp)
1111
 
    //We cant resolve the hostname
1112
 
    inet_address.s_addr=-1;
1113
 
  else
1114
 
    //We have the hostname
1115
 
    memcpy((char *)&inet_address,hp->h_addr,sizeof(struct in_addr));
1116
 
 
1117
 
  //The hostname was unresolvable, we cant connect to it
1118
 
  if (inet_address.s_addr==-1)
1119
 
    {
1120
 
      close(fd);
1121
 
      return 0;
1122
 
    }
1123
 
 
1124
 
  //Set the socket data
1125
 
  sa.sin_family=AF_INET;
1126
 
  sa.sin_port=htons(port);
1127
 
  sa.sin_addr=inet_address;
1128
 
 
1129
 
  //Set reuseaddr
1130
 
  dummy=1;
1131
 
  setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(char *)&dummy,sizeof(dummy));
1132
 
 
1133
 
 
1134
 
  //Set non-blocking, so we can check for a data without freezing
1135
 
 
1136
 
#ifdef FIONBIO
1137
 
  dummy=1;
1138
 
 
1139
 
  if (ioctl(fd,FIONBIO,&dummy)<0)
1140
 
    {
1141
 
      close(fd);
1142
 
      return 0;
1143
 
    }
1144
 
#else
1145
 
#  ifdef O_NONBLOCK
1146
 
  flags=fcntl(fd,F_GETFL,0);
1147
 
 
1148
 
  if (flags<0)
1149
 
    {
1150
 
      close(fd);
1151
 
      return 0;
1152
 
    }
1153
 
 
1154
 
  if (fcntl(fd,F_SETFL,flags|O_NONBLOCK)<0)
1155
 
    {
1156
 
      close(fd);
1157
 
      return 0;
1158
 
    }
1159
 
 
1160
 
# else
1161
 
#  error No valid non-blocking method - cannot build;
1162
 
# endif // O_NONBLOCK
1163
 
#endif //FIONBIO
1164
 
 
1165
 
 
1166
 
  //We have a valid socket, now we wrap a socketbuf around it
1167
 
  returnval=socket_create(fd);
1168
 
 
1169
 
  //Note the protocol
1170
 
  returnval->protocol=SOCKET_TCP;
1171
 
 
1172
 
  //Note the hostname and the portnumber in the structure
1173
 
  returnval->host=(char *)malloc(strlen(host)+1);
1174
 
  strcpy(returnval->host,host);
1175
 
  returnval->port=port;
1176
 
 
1177
 
  //Now try and actually connect to the remote address
1178
 
  if (connect(fd,(struct sockaddr *)&sa,sizeof(sa))==0)
1179
 
    {
1180
 
      //Connect was successful, we can finish this here
1181
 
      returnval->flags |= SOCKET_CONNECTED;
1182
 
      returnval->connect_time=time(NULL);
1183
 
 
1184
 
      return returnval;
1185
 
    }
1186
 
 
1187
 
  //We have an in-progress connection
1188
 
  if (errno==EINPROGRESS)
1189
 
    {
1190
 
      //Connect was possibly OK, but we havent finished, come back
1191
 
      //and check later with select
1192
 
      returnval->flags|=SOCKET_CONNECTING;
1193
 
 
1194
 
      if (!wait)
1195
 
        {
1196
 
          //The caller requested we do not wait for the connection to finish, 
1197
 
          //it will now be the callers responsibility to check this using
1198
 
          //process_socket
1199
 
          return returnval;
1200
 
        }
1201
 
      else
1202
 
        {
1203
 
          //We have been requested to keep on waiting for the connection
1204
 
          while (returnval->flags & SOCKET_CONNECTING)
1205
 
            {
1206
 
              //We do this by selecting on the socket, see what the
1207
 
              //writer returns
1208
 
              FD_ZERO(&writer);
1209
 
              FD_SET(returnval->fd,&writer);
1210
 
 
1211
 
              //Wait forever if needbe
1212
 
              selectnum=select(FD_SETSIZE,0,&writer,0,NULL);
1213
 
 
1214
 
              if (selectnum<0)
1215
 
                {
1216
 
                  //There was an error on the select, this means the connection
1217
 
                  //has definitely died.
1218
 
                  socket_destroy(returnval);
1219
 
                  return 0;
1220
 
                }
1221
 
              if (selectnum>0)
1222
 
                {
1223
 
                  if (FD_ISSET(returnval->fd,&writer))
1224
 
                    {
1225
 
                      //We have a writer, but is it ok or has it failed
1226
 
                      //to connect, check with getpeername()
1227
 
 
1228
 
                      peersize=sizeof(struct sockaddr_in);
1229
 
 
1230
 
                      if (!getpeername(returnval->fd,
1231
 
                                       (struct sockaddr *)&peername,
1232
 
                                       &peersize))
1233
 
                        {
1234
 
                          //Connected ok!
1235
 
                          returnval->flags &=~ SOCKET_CONNECTING;
1236
 
                          returnval->flags |= SOCKET_CONNECTED;
1237
 
                          returnval->connect_time=time(NULL);
1238
 
                          return returnval;
1239
 
                        }
1240
 
                      else
1241
 
                        {
1242
 
                          //Connection failed
1243
 
                          socket_destroy(returnval);
1244
 
                          return 0;
1245
 
                        }
1246
 
                    }
1247
 
                }
1248
 
            }
1249
 
        }
1250
 
    }
1251
 
 
1252
 
  //It was an error, and a bad one, close this
1253
 
  socket_destroy(returnval);
1254
 
 
1255
 
  return 0;
1256
 
}
1257
 
 
1258
 
//Create a UDP socket. Actually this never connects so the
1259
 
//wait parameter is ignored. It just sets up a route where data can be thrown
1260
 
//to. With UDP you dont know if it has reached its target or not.
1261
 
socketbuf *socket_create_inet_udp_wait(const char *host,int port,int wait)
1262
 
{
1263
 
  int fd,dummy;
1264
 
  socketbuf *returnval;
1265
 
  struct in_addr inet_address;
1266
 
  struct hostent *hp;
1267
 
#ifndef FIONBIO
1268
 
# ifdef O_NONBLOCK
1269
 
  int flags;
1270
 
# endif
1271
 
#endif
1272
 
 
1273
 
  //We need to know where to connect to.
1274
 
  if (!host || !*host)
1275
 
    return 0;
1276
 
 
1277
 
  //Create the socket
1278
 
  fd=socket(PF_INET,SOCK_DGRAM,IPPROTO_IP);
1279
 
  if (fd<1)
1280
 
    return 0;
1281
 
 
1282
 
  //Now create the data structure around the socket
1283
 
  returnval=socket_create(fd);
1284
 
 
1285
 
  memset(&returnval->udp_sa,0,sizeof(struct sockaddr_in));
1286
 
 
1287
 
  //Lookup the hostname we are sending to
1288
 
  hp=gethostbyname(host);
1289
 
  if (!hp)
1290
 
    inet_address.s_addr=-1;
1291
 
  else
1292
 
    memcpy((char *)&inet_address,hp->h_addr,sizeof(struct in_addr));
1293
 
 
1294
 
  if (inet_address.s_addr==-1)
1295
 
    {
1296
 
      //We couldnt resolve the address, destroy the socket
1297
 
      socket_destroy(returnval);
1298
 
      close(fd);
1299
 
      return 0;
1300
 
    }
1301
 
 
1302
 
  //Save the data for later use in the datastruct
1303
 
  returnval->udp_sa.sin_family=AF_INET;
1304
 
  returnval->udp_sa.sin_port=htons(port);
1305
 
  returnval->udp_sa.sin_addr.s_addr=inet_address.s_addr;
1306
 
 
1307
 
  //Note the protocol
1308
 
  returnval->protocol=SOCKET_UDP;
1309
 
 
1310
 
  //Save the text representation of the address
1311
 
  returnval->host=(char *)malloc(strlen(host)+1);
1312
 
  strcpy(returnval->host,host);
1313
 
  returnval->port=port;
1314
 
 
1315
 
 
1316
 
  //Set non-blocking, so we can check for a data without freezing
1317
 
 
1318
 
#ifdef FIONBIO
1319
 
  dummy=1;
1320
 
 
1321
 
  if (ioctl(fd,FIONBIO,&dummy)<0)
1322
 
    {
1323
 
      close(fd);
1324
 
      return 0;
1325
 
    }
1326
 
#else
1327
 
#  ifdef O_NONBLOCK
1328
 
  flags=fcntl(fd,F_GETFL,0);
1329
 
 
1330
 
  if (flags<0)
1331
 
    {
1332
 
      close(fd);
1333
 
      return 0;
1334
 
    }
1335
 
 
1336
 
  if (fcntl(fd,F_SETFL,flags|O_NONBLOCK)<0)
1337
 
    {
1338
 
      close(fd);
1339
 
      return 0;
1340
 
    }
1341
 
 
1342
 
# else
1343
 
#  error No valid non-blocking method - cannot build;
1344
 
# endif // O_NONBLOCK
1345
 
#endif //FIONBIO
1346
 
 
1347
 
  //While we technically havent connected, we are ready to send data, and thats
1348
 
  //what is important
1349
 
  returnval->flags |= SOCKET_CONNECTED;
1350
 
  returnval->connect_time=time(NULL);
1351
 
 
1352
 
  return returnval;
1353
 
}
1354
 
 
1355
 
//Test to see of a socket is connected
1356
 
int socket_connected(socketbuf *sock)
1357
 
{
1358
 
  if (sock->flags & SOCKET_DEAD)
1359
 
    //A dead socket is never connected
1360
 
    return 0;
1361
 
 
1362
 
  if (sock->flags & SOCKET_CONNECTED)
1363
 
    //It has connected
1364
 
    return 1;
1365
 
  
1366
 
  return 0;
1367
 
}
1368
 
 
1369
 
//Test to see if a socket is dead
1370
 
int socket_dead(socketbuf *sock)
1371
 
{
1372
 
  if (sock->flags & SOCKET_DEAD)
1373
 
    //It is {:-(
1374
 
    return 1;
1375
 
 
1376
 
  //Its alive! yay!
1377
 
  return 0;
1378
 
}
1379
 
 
1380
 
//This function drops a set length of data from the socket This is handy
1381
 
//For it we have already peeked it, so we HAVE the data, we dont want to
1382
 
//reallocate. Or if we have a set of data we KNOW is useless
1383
 
void socket_indata_drop(socketbuf *sock,int len)
1384
 
{
1385
 
  //memmove freaks out at a zero length memory move
1386
 
  if (len==0)
1387
 
    return;
1388
 
  
1389
 
  //Decrease the recorded amount of data stored
1390
 
  sock->indata->len-=len;
1391
 
 
1392
 
  if (sock->indata->len<1)
1393
 
    {
1394
 
      sock->indata->len=0;
1395
 
      return;
1396
 
    }
1397
 
 
1398
 
  //move the later data to the start of the buffer
1399
 
  memmove(sock->indata->buf,sock->indata->buf+len,sock->indata->len);
1400
 
  
1401
 
  return;
1402
 
}
1403
 
 
1404
 
//This function drops a set length of data from the socket OUTBUFFER
1405
 
//This is dangerous and is only an internal function, dont let the end user
1406
 
//do it or the whole socket could break, especially in UDP
1407
 
static void socket_outdata_drop(socketbuf *sock,int len)
1408
 
{
1409
 
  //memmove freaks out at a zero length memory move
1410
 
  if (len==0)
1411
 
    return;
1412
 
  
1413
 
  //Decriment the recorded amount of data
1414
 
  sock->outdata->len-=len;
1415
 
 
1416
 
  if (sock->outdata->len<1)
1417
 
    {
1418
 
      sock->outdata->len=0;
1419
 
      return;
1420
 
    }
1421
 
 
1422
 
  //Move the rest to the start
1423
 
  memmove(sock->outdata->buf,sock->outdata->buf+len,sock->outdata->len);
1424
 
  
1425
 
  return;
1426
 
}
1427
 
 
1428
 
//Free a UDP data packet Fairly obvious
1429
 
int socket_udp_data_free(socket_udp_data *data)
1430
 
{
1431
 
  if (data->data)
1432
 
    free(data->data);
1433
 
  free(data);
1434
 
 
1435
 
  return 1;
1436
 
}
1437
 
 
1438
 
//A 2 way UDP socket has received some data on its return socket
1439
 
static socket_udp_data *socket_udp2way_indata_action(socketbuf *sock,int pull)
1440
 
{
1441
 
  socket_udp_data *returnval;
1442
 
  socket_intchar len;
1443
 
  int datalen;
1444
 
 
1445
 
  //All data must be at least 4 bytes - this is the length of the data in the
1446
 
  //packet
1447
 
  if (sock->indata->len<4)
1448
 
    return NULL;
1449
 
 
1450
 
  //get the length of the data
1451
 
  memcpy(len.c,sock->indata->buf,4);
1452
 
 
1453
 
  datalen=len.i;
1454
 
 
1455
 
  //The packet isnt big enough to hold all the data we expected - this is a
1456
 
  //corrupted packet, ABORT!
1457
 
  if (datalen+4 > sock->indata->len)
1458
 
    return NULL;
1459
 
 
1460
 
  //Create an internal UDP packet to handle the data we have received
1461
 
  returnval=(socket_udp_data *)calloc(1,sizeof(socket_udp_data));
1462
 
 
1463
 
  //Allocate enough buffer for the incoming data
1464
 
  returnval->data=(char *)malloc(datalen);
1465
 
  memcpy(returnval->data,sock->indata->buf+4,datalen);
1466
 
 
1467
 
  returnval->length=datalen;
1468
 
 
1469
 
  //If we are deleting the data - then do so
1470
 
  if (pull)
1471
 
    socket_indata_drop(sock,datalen+4);
1472
 
 
1473
 
  //return the UDP data block
1474
 
  return returnval;
1475
 
}
1476
 
 
1477
 
//Receive a packet on a basic UDP socket
1478
 
static socket_udp_data *socket_udp_indata_action(socketbuf *sock,int pull)
1479
 
{
1480
 
  socket_udp_data *returnval;
1481
 
  socket_intchar len;
1482
 
  int sa_len;
1483
 
  int datalen;
1484
 
 
1485
 
  //We need to have at least 4 bytes as the length of the data in the packet
1486
 
  if (sock->indata->len<4)
1487
 
    return NULL;
1488
 
 
1489
 
  //If this is a 2 way UDP socket, process it using 2 way UDP handlers
1490
 
  if (sock->udp2w)
1491
 
    return socket_udp2way_indata_action(sock,pull);
1492
 
 
1493
 
  //Note the length of the sa structure - this is written wholesale
1494
 
  //into the buffer, this is actually OK
1495
 
  memcpy(len.c,sock->indata->buf,4);
1496
 
  sa_len=len.i;
1497
 
 
1498
 
 
1499
 
  //Check we have enough space
1500
 
  if (sa_len+8  > sock->indata->len)
1501
 
    return NULL;
1502
 
 
1503
 
  //Find the length of the data now.
1504
 
  memcpy(len.c,sock->indata->buf+4+sa_len,4);
1505
 
  datalen=len.i;
1506
 
 
1507
 
  //Check we have the whole data packet
1508
 
  if (sa_len+datalen+8 > sock->indata->len)
1509
 
    //We dont, its corrupt
1510
 
    return NULL;
1511
 
 
1512
 
  //Allocate a data structure for the packet
1513
 
  returnval=(socket_udp_data *)calloc(1,sizeof(socket_udp_data));
1514
 
 
1515
 
  //Store the sa in the data structure.
1516
 
  memcpy(&returnval->sa,sock->indata->buf+4,sa_len);
1517
 
 
1518
 
  //And the data itself
1519
 
  returnval->data=(char *)malloc(datalen);
1520
 
  memcpy(returnval->data,sock->indata->buf+8+sa_len,datalen);
1521
 
  
1522
 
  returnval->length=datalen;
1523
 
 
1524
 
  //If we are pulling instead of just looking, delete the data from the buffer
1525
 
  if (pull)
1526
 
    socket_indata_drop(sock,8+sa_len+datalen);
1527
 
 
1528
 
  //Return the UDP data packet
1529
 
  return returnval;
1530
 
}
1531
 
 
1532
 
 
1533
 
//Wrapper function for the user to pull UDP data from the buffer
1534
 
socket_udp_data *socket_udp_indata_pull(socketbuf *sock)
1535
 
{
1536
 
  return socket_udp_indata_action(sock,1);
1537
 
}
1538
 
 
1539
 
//Wrapper function for the user to look at UDP data without removing it
1540
 
//from the buffer
1541
 
socket_udp_data *socket_udp_indata_view(socketbuf *sock)
1542
 
{
1543
 
  return socket_udp_indata_action(sock,0);
1544
 
}
1545
 
 
1546
 
//This is a user function to pull data from any non-UDP socket
1547
 
char *socket_indata_pull(socketbuf *sock,int len)
1548
 
{
1549
 
  char *returnval;
1550
 
 
1551
 
  //Ensure we dont overrun
1552
 
  if (len > sock->indata->len)
1553
 
    len=sock->indata->len;
1554
 
 
1555
 
  //Allocate the return buffer
1556
 
  returnval=(char *)calloc(1,len+1);
1557
 
 
1558
 
  //copy the data
1559
 
  memcpy(returnval,sock->indata->buf,len);
1560
 
 
1561
 
  //Drop the data from the buffer
1562
 
  socket_indata_drop(sock,len);
1563
 
 
1564
 
  return returnval;
1565
 
}
1566
 
 
1567
 
//Allows the user to view the buffer
1568
 
const char *socket_indata_view(socketbuf *sock)
1569
 
{
1570
 
  //Just return the buffer. It is returned const so the user cant mess
1571
 
  //it up
1572
 
  return (char *)sock->indata->buf;
1573
 
}
1574
 
 
1575
 
//Find the length of the incoming data
1576
 
size_t socket_indata_length(socketbuf *sock)
1577
 
{
1578
 
  return sock->indata->len;
1579
 
}
1580
 
 
1581
 
size_t socket_outdata_length(socketbuf *sock)
1582
 
{
1583
 
  //find the length of data still to send
1584
 
  return sock->outdata->len;
1585
 
}
1586
 
 
1587
 
//Read a unix listener socket. Not a user function, this is an internal
1588
 
//function filtered down to when we know what kind of
1589
 
//socket we have.
1590
 
static int socket_read_listener_unix(socketbuf *sock)
1591
 
{
1592
 
  socketbuf *newsock;
1593
 
  socklen_t socklen;
1594
 
  struct sockaddr_un sa;
1595
 
  int fd,dummy=0;
1596
 
  struct linger lingerval;
1597
 
#ifndef FIONBIO
1598
 
  int flags;
1599
 
#endif
1600
 
 
1601
 
  //The length of the data passed into accept
1602
 
  socklen=(socklen_t)sizeof(sa);
1603
 
 
1604
 
  //Accept the new connection on this socket
1605
 
  fd = accept(sock->fd,(struct sockaddr *) &sa, &socklen);
1606
 
 
1607
 
  if (fd<1)
1608
 
    {
1609
 
      //The connection was bad, forget it
1610
 
      return 0;
1611
 
    }
1612
 
 
1613
 
  //Set non-blocking on the new socket
1614
 
#ifdef FIONBIO
1615
 
  dummy=1;
1616
 
  if (ioctl(fd,FIONBIO,&dummy)<0)
1617
 
    {
1618
 
      shutdown(fd,2);
1619
 
      close(fd);
1620
 
      return 0;
1621
 
    }
1622
 
#else
1623
 
# ifdef O_NONBLOCK
1624
 
  flags=fcntl(fd,F_GETFL,0);
1625
 
  if (flags < 0)
1626
 
    {
1627
 
      shutdown(fd,2);
1628
 
      close(fd);
1629
 
      return 0;
1630
 
    }
1631
 
  else
1632
 
    if (fcntl(fd,F_SETFL,flags|O_NONBLOCK) < 0)
1633
 
      {
1634
 
        shutdown(fd,2);
1635
 
        close(fd);
1636
 
        return 0;
1637
 
      }
1638
 
# else
1639
 
#  error no valid non-blocking method
1640
 
# endif
1641
 
#endif /*FIONBIO*/
1642
 
 
1643
 
  //We have a new non-blocking socket
1644
 
  dummy=1;
1645
 
  
1646
 
  //Set linger on this, to make sure all data possible is sent when the
1647
 
  //socket closes
1648
 
  lingerval.l_onoff=0;
1649
 
  lingerval.l_linger=0;
1650
 
  setsockopt(fd,SOL_SOCKET,SO_LINGER,(char *)&lingerval,
1651
 
             sizeof(struct linger));
1652
 
  
1653
 
  //Create the socketbuf to hold the fd
1654
 
  newsock=socket_create(fd);
1655
 
  newsock->protocol=SOCKET_UNIX;
1656
 
  newsock->path=(char *)malloc(strlen(sock->path)+1);
1657
 
  strcpy(newsock->path,sock->path);
1658
 
 
1659
 
  //This socket is automatically connected (thats what we've been doing)
1660
 
  newsock->flags |= (SOCKET_CONNECTED|SOCKET_INCOMING);
1661
 
 
1662
 
  //Set the mode to be the same as the socket that accepts (mode is things like
1663
 
  //sequential data and the like...
1664
 
  newsock->mode=sock->mode;
1665
 
 
1666
 
  //Set the parent.
1667
 
  newsock->parent=sock;
1668
 
 
1669
 
  //This is a new child, it is NOT acknowledged by the parent, so we simply
1670
 
  //put it into a queue waiting for the calling process to acknowledge we 
1671
 
  //exist
1672
 
  if (sock->new_children)
1673
 
    {
1674
 
      newsock->new_child_next=sock->new_children;
1675
 
      newsock->new_child_prev=newsock->new_child_next->new_child_prev;
1676
 
      newsock->new_child_next->new_child_prev=newsock;
1677
 
      newsock->new_child_prev->new_child_next=newsock;
1678
 
    }
1679
 
  else
1680
 
    {
1681
 
      newsock->new_child_next=newsock;
1682
 
      newsock->new_child_prev=newsock;
1683
 
      sock->new_children=newsock;
1684
 
    }
1685
 
 
1686
 
  newsock->connect_time=time(NULL);
1687
 
 
1688
 
#ifdef SOCK_SSL
1689
 
  if (sock->encrypted)
1690
 
    {
1691
 
      socket_set_server_key(newsock,sock->server_key_file);
1692
 
      socket_set_server_cert(newsock,sock->server_cert_file);
1693
 
      socket_set_encrypted(newsock);
1694
 
    }
1695
 
#endif
1696
 
 
1697
 
  return 1;
1698
 
}
1699
 
 
1700
 
//Some data has been received on the UDP socket. As UDP doesnt have connections
1701
 
//it just gets data thrown at it, this is unlike other listeners, as we 
1702
 
//dont just create a new socket here, we have to process the data we receive
1703
 
 
1704
 
static int socket_read_listener_inet_udp(socketbuf *sock,int failkill)
1705
 
{
1706
 
  int chars_left,chars_read,total_read;
1707
 
  void *buf;
1708
 
  char quickbuf[1024];
1709
 
  struct sockaddr_in sa;
1710
 
  socket_intchar len;
1711
 
  size_t sa_len;
1712
 
 
1713
 
  //Check how much data is there to read
1714
 
#ifdef FIONREAD
1715
 
  if (ioctl(sock->fd,FIONREAD,&chars_left)== -1)
1716
 
#else
1717
 
# ifdef I_NREAD
1718
 
  if (ioctl(sock->fd,I_NREAD,&chars_left)== -1)
1719
 
# else
1720
 
# error no valid read length method
1721
 
# endif
1722
 
#endif
1723
 
    {
1724
 
      if (failkill)
1725
 
        {
1726
 
          //The socket had no data, but it was supposed to, that means its
1727
 
          //dead
1728
 
          sock->flags|=SOCKET_DEAD;
1729
 
        }
1730
 
      return 0;
1731
 
    }
1732
 
 
1733
 
  /*Linkdeath*/
1734
 
  if (!chars_left)
1735
 
    {
1736
 
      if (failkill)
1737
 
        {
1738
 
          sock->flags|=SOCKET_DEAD;
1739
 
        }
1740
 
      return 0;
1741
 
    }
1742
 
 
1743
 
  //The buffer to store the data in. This is allocated statically as it gets
1744
 
  //used and reused and there is NO point in creating it time and time
1745
 
  //again **change** It wasnt threadsafe - oops
1746
 
  if (chars_left < 1024)
1747
 
    buf=quickbuf;
1748
 
  else
1749
 
    buf=malloc(chars_left);
1750
 
 
1751
 
  total_read=0;
1752
 
 
1753
 
  //Loop while there is data to read
1754
 
  while (chars_left>0)
1755
 
    {
1756
 
      sa_len=sizeof(struct sockaddr);
1757
 
 
1758
 
      //Actually perfrorm the read from the UDP socket
1759
 
      chars_read=recvfrom(sock->fd,
1760
 
                          buf,
1761
 
                          chars_left,
1762
 
                          0,
1763
 
                          (struct sockaddr *)&sa,
1764
 
                          &sa_len);
1765
 
 
1766
 
      if (chars_read==-1)
1767
 
        {
1768
 
          if (errno!=EAGAIN) /*An EAGAIN simply means that it wasnt quite ready
1769
 
                               so try again later.*/
1770
 
            {
1771
 
              //There was an error on the read, dead socket
1772
 
              sock->flags|=SOCKET_DEAD;
1773
 
            }
1774
 
          if (buf!=quickbuf)
1775
 
            free(buf);
1776
 
          return 0;
1777
 
        }
1778
 
 
1779
 
      if (chars_read==0)
1780
 
        {
1781
 
          //No chars were read, so nothing was ready, try again next time
1782
 
          if (buf!=quickbuf)
1783
 
            free(buf);
1784
 
          return 0;
1785
 
        }
1786
 
 
1787
 
      //Note that the socket received data, this is to stop it timing out,
1788
 
      //as UDP sockets are stateless
1789
 
      sock->udp2w_lastmsg=time(NULL);
1790
 
 
1791
 
#ifdef DEBUG
1792
 
      //if we are in debug mode, run that now
1793
 
      if (sock->debug)
1794
 
        socket_data_debug(sock,(char *)buf,chars_read,0);
1795
 
#endif
1796
 
 
1797
 
      //We are a 2 way UDP socket, process the data via the UDP2W data handler
1798
 
      if (sock->udp2w)
1799
 
        socket_udp2way_listener_data_process(sock,
1800
 
                                             &sa,sa_len,
1801
 
                                             (signed char *)buf,chars_read);
1802
 
      else
1803
 
        {
1804
 
          //We are a one way UDP socket
1805
 
 
1806
 
          //Add the sa to the datastream
1807
 
          len.i=sa_len;
1808
 
          dynstringRawappend(sock->indata,len.c,4);
1809
 
          dynstringRawappend(sock->indata,(char *)&sa,sa_len);
1810
 
 
1811
 
          //Then the data
1812
 
          len.i=chars_read;
1813
 
          dynstringRawappend(sock->indata,len.c,4);
1814
 
          dynstringRawappend(sock->indata,(char *)buf,chars_read);
1815
 
        }
1816
 
      //Note how many chars have been read, and loop back to see if we have
1817
 
      //another packets worth of data to read
1818
 
      chars_left-=chars_read;
1819
 
      sock->bytes_in+=chars_read;
1820
 
      total_read+=chars_read;
1821
 
    }
1822
 
 
1823
 
  if (buf!=quickbuf)
1824
 
    free(buf);
1825
 
 
1826
 
  //Try again for more packets, but bear in mind it is OK if there are none, so
1827
 
  //we set the failkill parameter to 0
1828
 
  socket_read_listener_inet_udp(sock,0);
1829
 
 
1830
 
  return total_read;
1831
 
}
1832
 
 
1833
 
//Read the listener of a TCPIP socket
1834
 
static int socket_read_listener_inet_tcp(socketbuf *sock)
1835
 
{
1836
 
  socketbuf *newsock;
1837
 
  socklen_t socklen;
1838
 
  struct sockaddr_in sa;
1839
 
  int fd,dummy=0;
1840
 
  struct linger lingerval;
1841
 
#ifndef FIONBIO
1842
 
  int flags;
1843
 
#endif
1844
 
 
1845
 
  //The length of the data passed into accept
1846
 
  socklen=(socklen_t)sizeof(sa);
1847
 
 
1848
 
  //Get the incoming socket
1849
 
  fd = accept(sock->fd,(struct sockaddr *) &sa, &socklen);
1850
 
 
1851
 
  if (fd<1)
1852
 
    {
1853
 
      //It was a bad socket, drop it
1854
 
      return 0;
1855
 
    }
1856
 
 
1857
 
  //Set it to be non-blocking
1858
 
#ifdef FIONBIO
1859
 
  dummy=1;
1860
 
  if (ioctl(fd,FIONBIO,&dummy)<0)
1861
 
    {
1862
 
      shutdown(fd,2);
1863
 
      close(fd);
1864
 
      return 0;
1865
 
    }
1866
 
#else
1867
 
# ifdef O_NONBLOCK
1868
 
  flags=fcntl(fd,F_GETFL,0);
1869
 
  if (flags < 0)
1870
 
    {
1871
 
      shutdown(fd,2);
1872
 
      close(fd);
1873
 
      return 0;
1874
 
    }
1875
 
  else
1876
 
    if (fcntl(fd,F_SETFL,flags|O_NONBLOCK) < 0)
1877
 
      {
1878
 
        shutdown(fd,2);
1879
 
        close(fd);
1880
 
        return 0;
1881
 
      }
1882
 
# else
1883
 
#  error no valid non-blocking method
1884
 
# endif  
1885
 
#endif /*FIONBIO*/
1886
 
 
1887
 
 
1888
 
  //Set linger so that the socket will send all its data when it close()s
1889
 
  lingerval.l_onoff=0;
1890
 
  lingerval.l_linger=0;
1891
 
  setsockopt(fd,SOL_SOCKET,SO_LINGER,(char *)&lingerval,
1892
 
             sizeof(struct linger));
1893
 
  
1894
 
  //Create the socketbuf to hold the socket
1895
 
  newsock=socket_create(fd);
1896
 
  newsock->protocol=SOCKET_TCP;
1897
 
  newsock->port=ntohs(sa.sin_port);
1898
 
  newsock->host=(char *)malloc(strlen(inet_ntoa(sa.sin_addr))+1);
1899
 
  strcpy(newsock->host,inet_ntoa(sa.sin_addr));
1900
 
 
1901
 
  //This is a connected socket so note it as such
1902
 
  newsock->flags |= (SOCKET_CONNECTED|SOCKET_INCOMING);
1903
 
  newsock->mode=sock->mode;
1904
 
 
1905
 
  //Link this into the parent so that the calling program can
1906
 
  //actually get hold of this socket
1907
 
  newsock->parent=sock;
1908
 
 
1909
 
  if (sock->new_children)
1910
 
    {
1911
 
      newsock->new_child_next=sock->new_children;
1912
 
      newsock->new_child_prev=newsock->new_child_next->new_child_prev;
1913
 
      newsock->new_child_next->new_child_prev=newsock;
1914
 
      newsock->new_child_prev->new_child_next=newsock;
1915
 
    }
1916
 
  else
1917
 
    {
1918
 
      newsock->new_child_next=newsock;
1919
 
      newsock->new_child_prev=newsock;
1920
 
      sock->new_children=newsock;
1921
 
    }
1922
 
 
1923
 
  newsock->connect_time=time(NULL);
1924
 
 
1925
 
 
1926
 
#ifdef SOCK_SSL
1927
 
  if (sock->encrypted)
1928
 
    {
1929
 
      socket_set_encrypted(newsock);
1930
 
    }
1931
 
#endif
1932
 
 
1933
 
  return 1;
1934
 
}
1935
 
 
1936
 
 
1937
 
//Generic function to wrap all listener read functions. It simply
1938
 
//Looks at the protocol and calls the appropriate function
1939
 
static int socket_read_listener(socketbuf *sock)
1940
 
{
1941
 
  switch (sock->protocol)
1942
 
    {
1943
 
    case SOCKET_TCP:
1944
 
      return socket_read_listener_inet_tcp(sock);
1945
 
      break;
1946
 
    case SOCKET_UDP:
1947
 
      return socket_read_listener_inet_udp(sock,1);
1948
 
      break;
1949
 
    case SOCKET_UNIX:
1950
 
      return socket_read_listener_unix(sock);
1951
 
      break;
1952
 
    case SOCKET_INTERRUPT:
1953
 
      return 0;
1954
 
      break;
1955
 
    }
1956
 
 
1957
 
  //Couldnt find a listener handler - erm, that cant happen!
1958
 
  return -1;
1959
 
}
1960
 
 
1961
 
//Read a 2 way UDP socket. This will be the return socket on the client,
1962
 
//as the outbound is read on the listener. Technicallt this is also a
1963
 
//listener but it can only belong to one socketbuf so we can skip a load
1964
 
//of the ownership tests that happen lower down the line
1965
 
static int socket_udp2way_read(socketbuf *sock,int failkill)
1966
 
{
1967
 
  int chars_left,chars_read,total_read;
1968
 
  void *buf=0;
1969
 
  char quickbuf[1024];
1970
 
  struct sockaddr_in sa;
1971
 
  size_t sa_len;
1972
 
 
1973
 
 
1974
 
  //Check how much data is there to read
1975
 
#ifdef FIONREAD
1976
 
  if (ioctl(sock->udp2w_infd,FIONREAD,&chars_left)== -1)
1977
 
#else
1978
 
# ifdef I_NREAD
1979
 
  if (ioctl(sock->udp2w_infd,I_NREAD,&chars_left)== -1)
1980
 
# else
1981
 
# error no valid read length method
1982
 
# endif
1983
 
#endif
1984
 
    {
1985
 
      if (failkill)
1986
 
        {
1987
 
          //Kill the socket, there is no data when we expected there would be
1988
 
          sock->flags|=SOCKET_DEAD;
1989
 
        }
1990
 
      return 0;
1991
 
    }
1992
 
 
1993
 
  /*Linkdeath*/
1994
 
  if (!chars_left)
1995
 
    {
1996
 
      if (failkill)
1997
 
        {
1998
 
          sock->flags|=SOCKET_DEAD;
1999
 
        }
2000
 
      return 0;
2001
 
    }
2002
 
 
2003
 
  //The buffer to store the data in. This is allocated statically as it gets
2004
 
  //used and reused and there is NO point in creating it time and time
2005
 
  //again
2006
 
  if (chars_left<1024)
2007
 
    buf=quickbuf;
2008
 
  else
2009
 
    buf=malloc(chars_left+1);
2010
 
 
2011
 
  total_read=0;
2012
 
 
2013
 
  //Loop while there is data to read
2014
 
  while (chars_left>0)
2015
 
    {
2016
 
      sa_len=sizeof(struct sockaddr);
2017
 
 
2018
 
      //Actually perfrorm the read from the UDP socket
2019
 
      chars_read=recvfrom(sock->udp2w_infd,
2020
 
                          buf,
2021
 
                          chars_left,
2022
 
                          0,
2023
 
                          (struct sockaddr *)&sa,
2024
 
                          &sa_len);
2025
 
 
2026
 
      if (chars_read==-1)
2027
 
        {
2028
 
          if (errno!=EAGAIN) /*An EAGAIN simply means that it wasnt quite ready
2029
 
                               so try again later.*/
2030
 
 
2031
 
            {
2032
 
              //There was an error on the read, dead socket
2033
 
              sock->flags|=SOCKET_DEAD;
2034
 
            }
2035
 
 
2036
 
          if (buf!=quickbuf)
2037
 
            free(buf);
2038
 
 
2039
 
          return 0;
2040
 
        }
2041
 
 
2042
 
      if (chars_read==0)
2043
 
        {
2044
 
          //No chars were read, so nothing was ready, try again next time
2045
 
          if (buf!=quickbuf)
2046
 
            free(buf);
2047
 
 
2048
 
          return 0;
2049
 
        }
2050
 
 
2051
 
      //Note that the socket received data, this is to stop it timing out,
2052
 
      //as UDP sockets are stateless
2053
 
      sock->udp2w_lastmsg=time(NULL);
2054
 
 
2055
 
#ifdef DEBUG
2056
 
      //if we are in debug mode, run that now
2057
 
      if (sock->debug)
2058
 
        socket_data_debug(sock,(char *)buf,chars_read,0);
2059
 
#endif
2060
 
 
2061
 
      //We ARE a 2 way UDP socket reader, pass this data off to that
2062
 
      //handler
2063
 
      socket_udp2way_reader_data_process(sock,(signed char *)buf,chars_read);
2064
 
 
2065
 
      //Note how many chars have been read, and loop back to see if we have
2066
 
      //another packets worth of data to read
2067
 
      chars_left-=chars_read;
2068
 
      sock->bytes_in+=chars_read;
2069
 
      total_read+=chars_read;
2070
 
    }
2071
 
  
2072
 
  if (buf!=quickbuf)
2073
 
    free(buf);
2074
 
 
2075
 
  //Try again for more packets, but bear in mind it is OK if there are none, so
2076
 
  //we set the failkill parameter to 0
2077
 
  socket_udp2way_read(sock,0);
2078
 
 
2079
 
  return total_read;
2080
 
}
2081
 
 
2082
 
//This is the generic function called to read data from the socket into the
2083
 
//socket buffer. This is not called by the user. The user just looks at the
2084
 
//buffer. This is called fro any type of socket, and the ones that this is not
2085
 
//appropriate for it just hands off to other functions. This is THE base read
2086
 
//functionf or ANY socket
2087
 
static int socket_read(socketbuf *sock)
2088
 
{
2089
 
  int chars_left,chars_read,total_read;
2090
 
  void *buf;
2091
 
  char quickbuf[1024];
2092
 
 
2093
 
  //Its a listener, read it differently using accepts
2094
 
  if (sock->flags & SOCKET_LISTENER)
2095
 
    return socket_read_listener(sock);
2096
 
 
2097
 
  //Its a UDP socket, all readable UDP sockets are listeners, you cant read
2098
 
  //an outbound UDP socket
2099
 
  if (sock->protocol==SOCKET_UDP)
2100
 
    return 0;
2101
 
 
2102
 
  //Check how much data there is coming in
2103
 
#ifdef FIONREAD
2104
 
  if (ioctl(sock->fd,FIONREAD,&chars_left)== -1)
2105
 
#else
2106
 
# ifdef I_NREAD
2107
 
  if (ioctl(sock->fd,I_NREAD,&chars_left)== -1)
2108
 
# else
2109
 
#  error no valid read length method
2110
 
# endif
2111
 
#endif
2112
 
    {
2113
 
      //The ioctl failed, this is a dead-socket case
2114
 
      sock->flags|=SOCKET_DEAD;
2115
 
      return 0;
2116
 
    }
2117
 
 
2118
 
  if (!chars_left)
2119
 
    {
2120
 
      /*Linkdeath*/
2121
 
      sock->flags|=SOCKET_DEAD;
2122
 
      return 0;
2123
 
    }
2124
 
 
2125
 
 
2126
 
  //The buffer to store the data in. This is allocated statically as it gets
2127
 
  //used and reused and there is NO point in creating it time and time
2128
 
  //again
2129
 
  if (chars_left < 1024)
2130
 
    buf=quickbuf;
2131
 
  else
2132
 
    buf=malloc(chars_left);
2133
 
 
2134
 
  total_read=0;
2135
 
 
2136
 
  //Keep on looping till all data has been read
2137
 
  while (chars_left>0)
2138
 
    {
2139
 
      //actually read the data from the socket
2140
 
#ifdef SOCK_SSL
2141
 
      if (sock->encrypted==1)
2142
 
        chars_read=SSL_read(sock->ssl,buf,chars_left);
2143
 
      else
2144
 
#endif
2145
 
        chars_read=read(sock->fd,buf,chars_left);
2146
 
 
2147
 
      if (chars_read==-1)
2148
 
        {
2149
 
          //there was an error
2150
 
          if (errno!=EAGAIN) //EAGAIN isnt bad, it just means try later
2151
 
            {
2152
 
              //Anything else is bad, the socket is dead
2153
 
              sock->flags|=SOCKET_DEAD;
2154
 
            }
2155
 
 
2156
 
          if (buf!=quickbuf)
2157
 
            free(buf);
2158
 
 
2159
 
          return 0;
2160
 
        }
2161
 
 
2162
 
      if (chars_read==0)
2163
 
        {
2164
 
          //No data was read, it shouldnt happen, if it does, then return from
2165
 
          //here.
2166
 
          if (buf!=quickbuf)
2167
 
            free(buf);
2168
 
 
2169
 
          return 0;
2170
 
        }
2171
 
 
2172
 
#ifdef DEBUG
2173
 
      //If we are in debug mode do that now
2174
 
      if (sock->debug)
2175
 
        socket_data_debug(sock,(char *)buf,chars_read,0);
2176
 
#endif
2177
 
 
2178
 
      //Add the read data into the indata buffer
2179
 
      if (sock->protocol!=SOCKET_INTERRUPT)
2180
 
        dynstringRawappend(sock->indata,(char *)buf,chars_read);
2181
 
      chars_left-=chars_read;
2182
 
      sock->bytes_in+=chars_read;
2183
 
      total_read+=chars_read;
2184
 
    }
2185
 
 
2186
 
  if (buf!=quickbuf)
2187
 
    free(buf);
2188
 
 
2189
 
  return total_read;
2190
 
}
2191
 
 
2192
 
//This function actually writes data to the socket. This is NEVER called by
2193
 
//the user, as the socket could be in any state, and calling from the user
2194
 
//would just break everything. This is called for stream sockets but not
2195
 
//for datagram sockets like UDP
2196
 
static int socket_process_write_stream(socketbuf *sock)
2197
 
{
2198
 
  int written;
2199
 
 
2200
 
  //Perform the write. Try and write as much as we can, as fast as we can
2201
 
  written=write(sock->fd,sock->outdata->buf,sock->outdata->len);
2202
 
  
2203
 
  if (written==-1)
2204
 
    {
2205
 
      //The write had an error
2206
 
      if (errno!=EAGAIN) /*EAGAIN simply means that the write buffer is full,
2207
 
                           try again later, no problem*/
2208
 
        {
2209
 
          //Any other error is fatal
2210
 
          sock->flags |= SOCKET_DEAD;
2211
 
        }
2212
 
    }
2213
 
  else if (written > 0)
2214
 
    {
2215
 
#ifdef DEBUG
2216
 
      //In debug mode, run the debug function
2217
 
      if (sock->debug)
2218
 
        socket_data_debug(sock,(char *)sock->outdata->buf,written,1);
2219
 
#endif
2220
 
 
2221
 
      //Drop the written data from the buffer
2222
 
      socket_outdata_drop(sock,written);
2223
 
    }
2224
 
 
2225
 
  //Return the number of bytes written, in case they are needed
2226
 
  return written;
2227
 
}
2228
 
 
2229
 
//This function actually writes data to the socket. This is NEVER called by
2230
 
//the user, as the socket could be in any state, and calling from the user
2231
 
//would just break everything. This is called for datagram sockets but not
2232
 
//for stream sockets like TCP or UNIX
2233
 
static int socket_process_write_dgram(socketbuf *sock)
2234
 
{
2235
 
  int written;
2236
 
  socket_intchar towrite;
2237
 
 
2238
 
  //The buffer contains one int of length data and then lots of data to
2239
 
  //indicate a packet that should be sent all at once
2240
 
  if (sock->outdata->len<4)
2241
 
    return 0;
2242
 
 
2243
 
  //This is the length
2244
 
  memcpy(towrite.c,sock->outdata->buf,4);
2245
 
 
2246
 
  //check we have enough data in the buffer to send it all
2247
 
  if (sock->outdata->len<4+towrite.i)
2248
 
    return 0;
2249
 
 
2250
 
  //We have enough, send the data. DO NOT send the initial length header,
2251
 
  //it will get included in the receive data anyway, so we dont have to send
2252
 
  //it twice
2253
 
  written=sendto(sock->fd,
2254
 
                 sock->outdata->buf+4,towrite.i,
2255
 
                 MSG_DONTWAIT,
2256
 
                 (struct sockaddr *)&sock->udp_sa,
2257
 
                 sizeof(struct sockaddr_in));
2258
 
 
2259
 
 
2260
 
  if (written==-1) //There was an error
2261
 
    {
2262
 
      if (errno==EMSGSIZE)
2263
 
        {
2264
 
          //Data too big, nothing we can do, drop the packet
2265
 
          socket_outdata_drop(sock,towrite.i+4);
2266
 
 
2267
 
          return 0;
2268
 
        }
2269
 
      else if (errno!=EAGAIN) //If the error was EAGAIN just try later
2270
 
        {
2271
 
          //The error was something fatal
2272
 
          sock->flags |= SOCKET_DEAD;
2273
 
          return 0;
2274
 
        }
2275
 
    }
2276
 
  else if (written > 0)
2277
 
    {
2278
 
      //There was data sent
2279
 
 
2280
 
#ifdef DEBUG
2281
 
      //If we are in debug mode, handle that
2282
 
      if (sock->debug)
2283
 
        socket_data_debug(sock,(char *)sock->outdata->buf+4,written,1);
2284
 
#endif
2285
 
 
2286
 
      //Drop the data from the buffer
2287
 
      socket_outdata_drop(sock,towrite.i+4);
2288
 
 
2289
 
      //Recurse so we send as much as we can now till its empty or we error
2290
 
      written += socket_process_write_dgram(sock);
2291
 
    }
2292
 
 
2293
 
  return written;
2294
 
}
2295
 
 
2296
 
//This is the generic function to handle writes for ALL sockets
2297
 
static int socket_process_write(socketbuf *sock)
2298
 
{
2299
 
  //Only if we are connected and we have something to send
2300
 
  if (socket_connected(sock) && sock->outdata && sock->outdata->len>0)
2301
 
    {
2302
 
#ifdef SOCK_SSL
2303
 
      if (sock->encrypted)
2304
 
        return SSL_write(sock->ssl,sock->outdata->buf,sock->outdata->len);
2305
 
      else
2306
 
#endif
2307
 
        {
2308
 
          if (sock->protocol==SOCKET_UDP)
2309
 
            return socket_process_write_dgram(sock);
2310
 
          else
2311
 
            return socket_process_write_stream(sock);
2312
 
        }
2313
 
    }
2314
 
 
2315
 
  return 0;
2316
 
}
2317
 
 
2318
 
//2 way UDP sockets will ping each other to keep the socket alive. They ping 
2319
 
//every 10 seconds. If the sockets go 60 seconds with no ping, then the 
2320
 
//socket is considered dead.
2321
 
static int process_pings(socketbuf *sock)
2322
 
{
2323
 
  socket_intchar val;
2324
 
  int written=0;
2325
 
  char buf[8];
2326
 
  time_t this_second;
2327
 
 
2328
 
  //Only ping 2 way UDP sockets
2329
 
  if (!sock->udp2w)
2330
 
    return 0;
2331
 
 
2332
 
  //Cant ping from a listener, a listener is inbound
2333
 
  if (sock->flags & SOCKET_LISTENER)
2334
 
    return 0;
2335
 
 
2336
 
  //Note the time
2337
 
  this_second=time(NULL);
2338
 
  
2339
 
  //Check we need to send a ping
2340
 
  if (sock->udp2w_nextping < this_second)
2341
 
    {
2342
 
      sock->udp2w_nextping = this_second+10;
2343
 
 
2344
 
      //Create the ping packet
2345
 
      val.i=htonl(SOCKET_UDP2W_PROTOCOL_PING);
2346
 
      memcpy(buf,val.c,4);
2347
 
      
2348
 
      val.i=htonl(sock->udp2w_port);
2349
 
      memcpy(buf+4,val.c,4);
2350
 
 
2351
 
      //Actually send the ping
2352
 
      written=sendto(sock->fd,
2353
 
                     buf,8,
2354
 
                     MSG_DONTWAIT,
2355
 
                     (struct sockaddr *)&sock->udp_sa,
2356
 
                     sizeof(struct sockaddr_in));
2357
 
      
2358
 
      if (written==-1)
2359
 
        {
2360
 
          if (errno!=EAGAIN)
2361
 
            {
2362
 
              //Note the socket as dead if we cant send it
2363
 
              sock->flags |= SOCKET_DEAD;
2364
 
              return 0;
2365
 
            }
2366
 
        }
2367
 
    }
2368
 
 
2369
 
  //Now we look at if its expired, over 60 seconds since any communication
2370
 
  if (sock->flags & SOCKET_CONNECTING)
2371
 
    {
2372
 
      //Or a much smaller 8 seconds if we are trying to connect
2373
 
      if (this_second>sock->udp2w_lastmsg+8)
2374
 
        {
2375
 
          sock->flags |= SOCKET_DEAD;
2376
 
        }
2377
 
    }
2378
 
  else
2379
 
    {
2380
 
      if (this_second>sock->udp2w_lastmsg+60)
2381
 
        {
2382
 
          sock->flags |= SOCKET_DEAD;
2383
 
        }
2384
 
    }
2385
 
 
2386
 
  return written;
2387
 
}
2388
 
 
2389
 
//This function handles reliable UDP resending packets. UDP does not
2390
 
//guarentee transmission, so when we send a reliable packet, we get a repsonse
2391
 
//from the other end. When that response comes through we can assume the
2392
 
//packet is ok. Until then, we keep resending it on a time that is based on
2393
 
//the average round trip packet time. This allows for congested networks
2394
 
static int process_resends(socketbuf *sock)
2395
 
{
2396
 
  struct timeval time_now,target_time;
2397
 
  long long us;
2398
 
  socket_udp_rdata *scan;
2399
 
  int newlen;
2400
 
  socket_intchar udplen,udpdata;
2401
 
 
2402
 
  //Only do this for 2 way UDP sockets
2403
 
  if (!sock->udp2w)
2404
 
    return 0;
2405
 
 
2406
 
  //If there are no outbound packets to confirm, nothing to do
2407
 
  if (!sock->udp2w_routpacket)
2408
 
    return 0;
2409
 
 
2410
 
 
2411
 
  //Now we need to find the exact time, as well as find which ones need 
2412
 
  //resending
2413
 
  gettimeofday(&time_now,NULL);
2414
 
 
2415
 
  //Find how old a packet needs to be
2416
 
  us=sock->udp2w_averound/5; //Twice as long as average for a resend,/10*2 = /5
2417
 
 
2418
 
  target_time.tv_sec=time_now.tv_sec-(us/1000000);
2419
 
  target_time.tv_usec=time_now.tv_usec-(us%1000000);
2420
 
 
2421
 
  if (target_time.tv_usec<0)
2422
 
    {
2423
 
      target_time.tv_usec+=1000000;
2424
 
      target_time.tv_sec--;
2425
 
    }
2426
 
 
2427
 
  scan=sock->udp2w_rdata_out;
2428
 
 
2429
 
  while (scan)
2430
 
    {
2431
 
      //Loop through checking each packet
2432
 
 
2433
 
      if (target_time.tv_sec > scan->sendtime.tv_sec ||
2434
 
          (target_time.tv_sec == scan->sendtime.tv_sec &&
2435
 
           target_time.tv_usec > scan->sendtime.tv_usec))
2436
 
        {
2437
 
          //This packet needs resending
2438
 
 
2439
 
          //Find the length the packet needs to be
2440
 
          newlen=scan->length;
2441
 
          newlen+=8;
2442
 
          if (sock->udp2w_infd)
2443
 
            newlen+=4;
2444
 
 
2445
 
          //Set this length into the buffer
2446
 
          udplen.i=newlen;
2447
 
          dynstringRawappend(sock->outdata,udplen.c,4);
2448
 
          
2449
 
          //Send the protocol
2450
 
          udpdata.i=htonl(SOCKET_UDP2W_PROTOCOL_RDATA);
2451
 
 
2452
 
          dynstringRawappend(sock->outdata,udpdata.c,4);
2453
 
          
2454
 
          //Send the port
2455
 
          if (sock->udp2w_infd)
2456
 
            {
2457
 
              udpdata.i=htonl(sock->udp2w_port);
2458
 
              dynstringRawappend(sock->outdata,udpdata.c,4);
2459
 
            }
2460
 
          
2461
 
          //Send the packet number
2462
 
          udpdata.i=htonl(scan->packetnum);
2463
 
          dynstringRawappend(sock->outdata,udpdata.c,4);
2464
 
          
2465
 
          //Send the data
2466
 
          dynstringRawappend(sock->outdata,scan->data,scan->length);
2467
 
 
2468
 
          //note the new send time
2469
 
          scan->sendtime.tv_sec=time_now.tv_sec;
2470
 
          scan->sendtime.tv_usec=time_now.tv_usec;
2471
 
        }
2472
 
 
2473
 
      //Next packet
2474
 
      scan=scan->next;
2475
 
      if (scan==sock->udp2w_rdata_out)
2476
 
        scan=NULL;
2477
 
    }
2478
 
 
2479
 
  return 0;
2480
 
}
2481
 
 
2482
 
//This is the main function called to process user sockets. It handles
2483
 
//calls to both input and output as well as processing incoming sockets
2484
 
//and noting dead sockets as being dead. This is a program-called
2485
 
//function and should be called often.
2486
 
//Actual data is NOT returned from this function, this function simply
2487
 
//calls appropriate subfunctions which update the internal buffers of
2488
 
//sockets. It is the calling programs job to process this data.
2489
 
int socket_process_sockets(socket_processlist *list,long int timeout)
2490
 
{
2491
 
  socket_processlist *scan;
2492
 
  socketbuf *sock;
2493
 
  fd_set readers,writers;
2494
 
  struct timeval select_timeout;
2495
 
  int count,selectnum;
2496
 
 
2497
 
  scan=list;
2498
 
 
2499
 
  //Loop through each socket in the list we have been handed
2500
 
  while (scan)
2501
 
    {
2502
 
      sock=scan->sock;
2503
 
 
2504
 
      if (sock->udp2w)
2505
 
        {
2506
 
          //If the socket is a 2 way UDP socket, process resends and pings
2507
 
          process_resends(sock);
2508
 
          process_pings(sock);
2509
 
        }
2510
 
 
2511
 
      //Now process outbound writes (that will include any resends that have
2512
 
      //just been created
2513
 
#ifdef SOCK_SSL
2514
 
      if (sock->encrypted>1)
2515
 
        socket_process_ssl(sock);
2516
 
      else 
2517
 
#endif
2518
 
        socket_process_write(sock);
2519
 
 
2520
 
      scan=scan->next;
2521
 
      if (scan==list)
2522
 
        scan=NULL;
2523
 
    }  
2524
 
 
2525
 
  count=0;
2526
 
  FD_ZERO(&readers);
2527
 
  FD_ZERO(&writers);
2528
 
 
2529
 
  scan=list;
2530
 
 
2531
 
  //Loop through all sockets again
2532
 
  while (scan)
2533
 
    {
2534
 
      sock=scan->sock;
2535
 
 
2536
 
      //If the socket is alive
2537
 
      if (
2538
 
#ifdef SOCK_SSL
2539
 
          sock->encrypted<2 && 
2540
 
#endif
2541
 
          !(sock->flags & SOCKET_DEAD))
2542
 
        {
2543
 
          if (sock->flags & SOCKET_CONNECTING)
2544
 
            {
2545
 
              //This is a socket in the connecting state. See if it has now
2546
 
              //connected
2547
 
              if (sock->udp2w)
2548
 
                {
2549
 
                  //A connecting 2 way socket is one we need to send a 
2550
 
                  //connection message to again
2551
 
                  socket_udp2way_connectmessage(sock);
2552
 
 
2553
 
                  if (sock->udp2w_infd)
2554
 
                    {
2555
 
                      //Now set its reader socket to look for a response
2556
 
                      FD_SET(sock->udp2w_infd,&readers);
2557
 
                      count++;
2558
 
                    }
2559
 
                }
2560
 
              else
2561
 
                {
2562
 
                  //This socket should be set as a writer, as this will change
2563
 
                  //when a stream socket connection state changes
2564
 
                  FD_SET(sock->fd,&writers);
2565
 
                  count++;
2566
 
                }
2567
 
            }
2568
 
          else if (sock->flags & SOCKET_CONNECTED)
2569
 
            {
2570
 
              //This socket is alredy connected
2571
 
              if (sock->udp2w_infd)
2572
 
                {
2573
 
                  //If tehre is a UDP reading socket, we must use that to read
2574
 
                  FD_SET(sock->udp2w_infd,&readers);
2575
 
                  count++;
2576
 
                }
2577
 
              else
2578
 
                {
2579
 
                  //Set the main socket as a reader
2580
 
                  FD_SET(sock->fd,&readers);
2581
 
                  count++;
2582
 
                }
2583
 
            }
2584
 
        }
2585
 
 
2586
 
      scan=scan->next;
2587
 
      if (scan==list)
2588
 
        scan=NULL;
2589
 
    }
2590
 
 
2591
 
  if (!count)
2592
 
    //No valid sockets were ready to read, no point in reading them
2593
 
    return 0;
2594
 
 
2595
 
  //Set the timeout to be as requested by the caller
2596
 
  select_timeout.tv_sec=timeout/1000000;
2597
 
  select_timeout.tv_usec=timeout%1000000;
2598
 
 
2599
 
  //Now actually run the select
2600
 
  selectnum=select(FD_SETSIZE,&readers,&writers,0,&select_timeout);
2601
 
 
2602
 
  if (selectnum<1)
2603
 
    //Select was an error, or had no returns, we have nothing new to do now
2604
 
    return 0;
2605
 
 
2606
 
  //We have a result
2607
 
 
2608
 
 
2609
 
  //Loop through all sockets see what we can see
2610
 
  scan=list;
2611
 
 
2612
 
  while (scan)
2613
 
    {
2614
 
      sock=scan->sock;
2615
 
      if (
2616
 
#ifdef SOCK_SSL
2617
 
          sock->encrypted<2 && 
2618
 
#endif
2619
 
          !(sock->flags & SOCKET_DEAD))
2620
 
        {
2621
 
          if (sock->flags & SOCKET_CONNECTING)
2622
 
            {
2623
 
              //A connecting socket
2624
 
              if (sock->udp2w_infd)
2625
 
                {
2626
 
                  //Its a 2 way UDP - if it had any data
2627
 
                  if (FD_ISSET(sock->udp2w_infd,&readers))
2628
 
                    //Then send this to be processed. This will handle the
2629
 
                    //connection data if that is what is received
2630
 
                    socket_udp2way_read(sock,1);
2631
 
                }
2632
 
              else
2633
 
                {
2634
 
                  //Nothing here for a UDP socket
2635
 
                  if (sock->protocol!=SOCKET_UDP)
2636
 
                    {
2637
 
                      //If it has a writer, we simply assume it is done and 
2638
 
                      //the first write will fail. Not very efficient but
2639
 
                      //it works
2640
 
                      if (FD_ISSET(sock->fd,&writers))
2641
 
                        {
2642
 
                          sock->flags &=~ SOCKET_CONNECTING;
2643
 
                          sock->flags |= SOCKET_CONNECTED;
2644
 
                          sock->flags |= SOCKET_DELAYED_NOW_CONNECTED;
2645
 
                          sock->connect_time=time(NULL);
2646
 
                        }
2647
 
                    }
2648
 
                }
2649
 
            }
2650
 
          else if (sock->flags & SOCKET_CONNECTED)
2651
 
            {
2652
 
              //This is a connected socket, handle it
2653
 
 
2654
 
              if (sock->udp2w_infd)
2655
 
                {
2656
 
                  //2 way UDP socket reader
2657
 
                  if (FD_ISSET(sock->udp2w_infd,&readers))
2658
 
                    //Handle its special data
2659
 
                    socket_udp2way_read(sock,1);
2660
 
                }
2661
 
              else
2662
 
                {
2663
 
                  if (FD_ISSET(sock->fd,&readers))
2664
 
                    {
2665
 
                      //Any other socket, read it using the generic read function
2666
 
                      socket_read(sock);
2667
 
                    }
2668
 
                }
2669
 
            }
2670
 
        }
2671
 
 
2672
 
      scan=scan->next;
2673
 
      if (scan==list)
2674
 
        scan=NULL;
2675
 
    }
2676
 
 
2677
 
  //We're done, return how many sockets were affected
2678
 
  return count;
2679
 
}
2680
 
 
2681
 
 
2682
 
//This is a wrapper function for processing one single socket. It makes it
2683
 
//into a socketlist of one entry, and sends it to the previous
2684
 
//function for handling.
2685
 
int socket_process(socketbuf *sock,long int timeout)
2686
 
{
2687
 
  socket_processlist listofone;
2688
 
 
2689
 
  listofone.next=&listofone;
2690
 
  listofone.prev=&listofone;
2691
 
  listofone.sock=sock;
2692
 
 
2693
 
  return socket_process_sockets(&listofone,timeout);
2694
 
}
2695
 
 
2696
 
//Wrapper function to create a unix socket. It is assumed that wait is the
2697
 
//required functionality
2698
 
socketbuf *socket_create_unix(const char *path)
2699
 
{
2700
 
  return socket_create_unix_wait(path,1);
2701
 
}
2702
 
 
2703
 
//Wrapper function to create a TCPIP socket. It is assumed that wait is the
2704
 
//required functionality
2705
 
socketbuf *socket_create_inet_tcp(const char *host,int port)
2706
 
{
2707
 
  return socket_create_inet_tcp_wait(host,port,1);
2708
 
}
2709
 
 
2710
 
//Create a tcpip socket on a specific IP address
2711
 
socketbuf *socket_create_inet_tcp_listener_on_ip(const char *localip,int port)
2712
 
{
2713
 
  struct sockaddr_in sa;
2714
 
  int dummy=0;
2715
 
  char hostname[HOST_NAME_MAX+1];
2716
 
  struct hostent *hp;
2717
 
  int fd;
2718
 
  socketbuf *sock;
2719
 
  struct in_addr inet_address;
2720
 
  struct linger lingerval;
2721
 
#ifndef FIONBIO
2722
 
#ifdef O_NONBLOCK
2723
 
  int flags;
2724
 
#endif
2725
 
#endif
2726
 
 
2727
 
  //set the hostname. If this is passed in, use that, otherwise use gethostname
2728
 
  memset(&sa,0,sizeof(struct sockaddr_in));
2729
 
  if (localip)
2730
 
    strcpy(hostname,localip);
2731
 
  else
2732
 
    gethostname(hostname,HOST_NAME_MAX);
2733
 
 
2734
 
  //Simply gethostbyname which handles all kinds of addresses
2735
 
  hp=gethostbyname(hostname);
2736
 
 
2737
 
  if (!hp)
2738
 
    //We couldnt resolve the host fail
2739
 
    return 0;
2740
 
 
2741
 
  if (localip)
2742
 
    {
2743
 
      //Se specifically requested an IP address, so we use it, thus restricting
2744
 
      //to just one interface. If we didnt specify the address then we skip
2745
 
      //this section which in effect means that the socket will bind to all
2746
 
      //IP addresses on the system
2747
 
      memcpy((char *)&inet_address,hp->h_addr,sizeof(struct in_addr));
2748
 
      if (inet_address.s_addr!=-1)
2749
 
        sa.sin_addr.s_addr=inet_address.s_addr;
2750
 
    }
2751
 
  sa.sin_family=hp->h_addrtype;
2752
 
  sa.sin_port = htons(port);
2753
 
 
2754
 
  //Create the socket
2755
 
  fd = socket(AF_INET,SOCK_STREAM,0);
2756
 
  
2757
 
  if (fd < 0)
2758
 
    {
2759
 
      //We couldnt create the socket!
2760
 
      return 0;
2761
 
    }
2762
 
 
2763
 
  dummy=1;
2764
 
  //Set REUSEADDR so that if the system goes down it can go right 
2765
 
  //back up again. Otherwise it will block until all data is processed
2766
 
  setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(char *)&dummy,sizeof(dummy));
2767
 
 
2768
 
  //Linger so that data is sent when the socket closes
2769
 
  lingerval.l_onoff=0;
2770
 
  lingerval.l_linger=0;
2771
 
  setsockopt(fd,SOL_SOCKET,SO_LINGER,(char *)&lingerval,
2772
 
             sizeof(struct linger));
2773
 
 
2774
 
  //set non-blocking
2775
 
#ifdef FIONBIO
2776
 
  dummy=1;
2777
 
  if (ioctl(fd,FIONBIO,&dummy)<0)
2778
 
    {
2779
 
      close(fd);
2780
 
      return 0;
2781
 
    }
2782
 
#else
2783
 
# ifdef O_NONBLOCK
2784
 
  flags=fcntl(fd,F_GETFL,0);
2785
 
  if (flags < 0)
2786
 
    {
2787
 
      close(fd);
2788
 
      return 0;
2789
 
    }
2790
 
  else
2791
 
    if (fcntl(fd,F_SETFL,flags|O_NONBLOCK) < 0)
2792
 
      {
2793
 
        close(fd);
2794
 
        return 0;
2795
 
      }
2796
 
# else
2797
 
#  error no valid non-blocking method
2798
 
# endif
2799
 
#endif /*FIONBIO*/
2800
 
 
2801
 
  //Now bind the socket to the port
2802
 
  if (bind(fd,(struct sockaddr *)&sa,sizeof(sa))<0)
2803
 
    {
2804
 
      //We failed, maybe something else is already bound, maybe something
2805
 
      //else, regardless, we're stuffed
2806
 
      shutdown(fd,2);
2807
 
      close(fd);
2808
 
      return 0;
2809
 
    }
2810
 
 
2811
 
  //Listen with the maximum number - this means we can have as many incoming
2812
 
  //connections as the kernel is configured to handle (on the machine that
2813
 
  //builds of course, it wont magically change itself from machine to machine)
2814
 
  if (listen(fd,SOMAXCONN)<0)
2815
 
    {
2816
 
      shutdown(fd,2);
2817
 
      close(fd);
2818
 
      return 0;
2819
 
    }
2820
 
  
2821
 
  //Finally create the socket datastruct to hold the socket
2822
 
  sock=socket_create(fd);
2823
 
  sock->protocol=SOCKET_TCP;
2824
 
  sock->port=port;
2825
 
 
2826
 
  sock->flags |= (SOCKET_CONNECTED|SOCKET_LISTENER);
2827
 
  sock->connect_time=time(NULL);
2828
 
 
2829
 
  return sock;
2830
 
}
2831
 
 
2832
 
//Create a listener on ALL sockets
2833
 
socketbuf *socket_create_inet_tcp_listener(int port)
2834
 
{
2835
 
  return socket_create_inet_tcp_listener_on_ip(NULL,port);
2836
 
}
2837
 
 
2838
 
//Create a UDP listener
2839
 
socketbuf *socket_create_inet_udp_listener_on_ip(const char *localip,int port)
2840
 
{
2841
 
  struct sockaddr_in sa;
2842
 
  int dummy=0;
2843
 
  char hostname[HOST_NAME_MAX+1];
2844
 
  struct hostent *hp;
2845
 
  int fd;
2846
 
  socketbuf *sock;
2847
 
  struct in_addr inet_address;
2848
 
  struct linger lingerval;
2849
 
#ifndef FIONBIO
2850
 
#ifdef O_NONBLOCK
2851
 
  int flags;
2852
 
#endif
2853
 
#endif
2854
 
 
2855
 
  memset(&sa,0,sizeof(struct sockaddr_in));
2856
 
 
2857
 
  //set the hostname. If this is passed in, use that, otherwise use gethostname
2858
 
  if (localip)
2859
 
    strcpy(hostname,localip);
2860
 
  else
2861
 
    gethostname(hostname,HOST_NAME_MAX);
2862
 
 
2863
 
  //Simply gethostbyname which handles all kinds of addresses
2864
 
  hp=gethostbyname(hostname);
2865
 
 
2866
 
  if (!hp)
2867
 
    //We couldnt resolve the host fail
2868
 
    return 0;
2869
 
 
2870
 
  if (localip)
2871
 
    {
2872
 
      //We specifically requested an IP address, so we use it, thus restricting
2873
 
      //to just one interface. If we didnt specify the address then we skip
2874
 
      //this section which in effect means that the socket will bind to all
2875
 
      //IP addresses on the system
2876
 
      memcpy((char *)&inet_address,hp->h_addr,sizeof(struct in_addr));
2877
 
      if (inet_address.s_addr!=-1)
2878
 
        sa.sin_addr=inet_address;
2879
 
    }
2880
 
  sa.sin_family=hp->h_addrtype;
2881
 
  sa.sin_port = htons(port);
2882
 
 
2883
 
  //Create the socket
2884
 
  fd = socket(PF_INET,SOCK_DGRAM,IPPROTO_IP);
2885
 
  
2886
 
  if (fd < 0)
2887
 
    {
2888
 
      //We couldnt create the socket!
2889
 
      return 0;
2890
 
    }
2891
 
 
2892
 
  lingerval.l_onoff=0;
2893
 
  lingerval.l_linger=0;
2894
 
  setsockopt(fd,SOL_SOCKET,SO_LINGER,(char *)&lingerval,
2895
 
             sizeof(struct linger));
2896
 
 
2897
 
 
2898
 
  //Set non-blocking
2899
 
#ifdef FIONBIO
2900
 
  dummy=1;
2901
 
  if (ioctl(fd,FIONBIO,&dummy)<0)
2902
 
    {
2903
 
      close(fd);
2904
 
      return 0;
2905
 
    }
2906
 
#else
2907
 
# ifdef O_NONBLOCK
2908
 
  flags=fcntl(fd,F_GETFL,0);
2909
 
  if (flags < 0)
2910
 
    {
2911
 
      close(fd);
2912
 
      return 0;
2913
 
    }
2914
 
  else
2915
 
    if (fcntl(fd,F_SETFL,flags|O_NONBLOCK) < 0)
2916
 
      {
2917
 
        close(fd);
2918
 
        return 0;
2919
 
      }
2920
 
# else
2921
 
#  error no valid non-blocking method
2922
 
# endif
2923
 
#endif /*FIONBIO*/
2924
 
 
2925
 
  //Bind to the port
2926
 
  if (bind(fd,(struct sockaddr *)&sa,sizeof(sa))<0)
2927
 
    {
2928
 
      //We failed, maybe something else is already bound, maybe something
2929
 
      //else, regardless, we're stuffed
2930
 
      shutdown(fd,2);
2931
 
      close(fd);
2932
 
      return 0;
2933
 
    }
2934
 
 
2935
 
  //Finally create the socket datastruct to hold the socket
2936
 
  sock=socket_create(fd);
2937
 
  sock->protocol=SOCKET_UDP;
2938
 
  sock->port=port;
2939
 
 
2940
 
  sock->flags |= (SOCKET_CONNECTED|SOCKET_LISTENER);
2941
 
  sock->connect_time=time(NULL);
2942
 
 
2943
 
  return sock;
2944
 
}
2945
 
 
2946
 
//A wrapper function to bind a UDP listener on all interfaces
2947
 
socketbuf *socket_create_inet_udp_listener(int port)
2948
 
{
2949
 
  return socket_create_inet_udp_listener_on_ip(NULL,port);
2950
 
}
2951
 
 
2952
 
//Create a unix socket listener.
2953
 
socketbuf *socket_create_unix_listener(const char *path)
2954
 
{
2955
 
  int fd,dummy;
2956
 
  socketbuf *sock;
2957
 
  struct sockaddr_un sa;
2958
 
  struct linger lingerval;
2959
 
 
2960
 
  //Create the socket
2961
 
  fd = socket(PF_UNIX,SOCK_STREAM,0);
2962
 
 
2963
 
  if (fd < 1)
2964
 
    //Socket creation failed
2965
 
    return 0;
2966
 
 
2967
 
  //Set the socket types
2968
 
  sa.sun_family = AF_UNIX;
2969
 
  strcpy(sa.sun_path,path);
2970
 
 
2971
 
  //Set this to linger so any data being processed will be finished
2972
 
  lingerval.l_onoff=0;
2973
 
  lingerval.l_linger=0;
2974
 
  setsockopt(fd,SOL_SOCKET,SO_LINGER,(char *)&lingerval,
2975
 
             sizeof(struct linger));
2976
 
 
2977
 
 
2978
 
  //Set nonblocking
2979
 
#ifdef FIONBIO
2980
 
  dummy=1;
2981
 
  if (ioctl(fd,FIONBIO,&dummy)<0)
2982
 
    {
2983
 
      close(fd);
2984
 
      return 0;
2985
 
    }
2986
 
#else
2987
 
# ifdef O_NONBLOCK
2988
 
  flags=fcntl(fd,F_GETFL,0);
2989
 
  if (flags < 0)
2990
 
    {
2991
 
      close(fd);
2992
 
      return 0;
2993
 
    }
2994
 
  else
2995
 
    if (fcntl(fd,F_SETFL,flags|O_NONBLOCK) < 0)
2996
 
      {
2997
 
        close(fd);
2998
 
        return 0;
2999
 
      }
3000
 
# else
3001
 
#  error no valid non-blocking method
3002
 
# endif
3003
 
#endif /*FIONBIO*/
3004
 
 
3005
 
 
3006
 
  //Now bind to the location
3007
 
  if (bind(fd,(struct sockaddr *)&sa,sizeof(sa)) < 0)
3008
 
    {
3009
 
      //We failed. Maybe the file is already there...
3010
 
      close(fd);
3011
 
      return 0;
3012
 
    }
3013
 
 
3014
 
  //Listen with the maximum number - this means we can have as many incoming
3015
 
  //connections as the kernel is configured to handle (on the machine that
3016
 
  //builds of course, it wont magically change itself from machine to machine)
3017
 
  if (listen(fd,SOMAXCONN) < 0)
3018
 
    {
3019
 
      shutdown(fd,2);
3020
 
      close(fd);
3021
 
      unlink(path);
3022
 
      return 0;
3023
 
    }
3024
 
 
3025
 
  //Finally create the socket datastruct to hold the socket
3026
 
  sock=socket_create(fd);
3027
 
  sock->protocol=SOCKET_UNIX;
3028
 
  sock->path=(char *)malloc(strlen(path)+1);
3029
 
  strcpy(sock->path,path);
3030
 
 
3031
 
  sock->flags |= (SOCKET_CONNECTED|SOCKET_LISTENER);
3032
 
  sock->connect_time=time(NULL);
3033
 
 
3034
 
  return sock;
3035
 
}
3036
 
 
3037
 
//This is the function used by the calling program to see if any new 
3038
 
//connections have come in on a listener socket
3039
 
socketbuf *socket_new(socketbuf *parent)
3040
 
{
3041
 
  socketbuf *returnval;
3042
 
 
3043
 
  //Destroy any sockets that have died in the connection process. This doesnt
3044
 
  //get them all, just the first ones, until the one at the front is a live.
3045
 
  //This assumes that this function is called often, and so dead connections
3046
 
  //are cleaned up regularly.
3047
 
  while (parent->new_children && socket_dead(parent->new_children))
3048
 
    {
3049
 
      returnval=parent->new_children;
3050
 
 
3051
 
      //Unlink the dead socket
3052
 
      parent->new_children=parent->new_children->new_child_next;
3053
 
 
3054
 
      if (parent->new_children==returnval)
3055
 
        {
3056
 
          parent->new_children=NULL;
3057
 
          returnval->new_child_next=NULL;
3058
 
          returnval->new_child_prev=NULL;
3059
 
        }
3060
 
      else
3061
 
        {
3062
 
          returnval->new_child_next->new_child_prev=returnval->new_child_prev;
3063
 
          returnval->new_child_prev->new_child_next=returnval->new_child_next;
3064
 
        }
3065
 
      //destroy it
3066
 
      socket_destroy(returnval);
3067
 
    }
3068
 
 
3069
 
  //Now look for new sockets
3070
 
  if (parent->new_children)
3071
 
    {
3072
 
      returnval=parent->new_children;
3073
 
 
3074
 
      //Unlink the first socket from the list of new connections
3075
 
      parent->new_children=parent->new_children->new_child_next;
3076
 
      
3077
 
      if (parent->new_children==returnval)
3078
 
        {
3079
 
          parent->new_children=NULL;
3080
 
          returnval->new_child_next=NULL;
3081
 
          returnval->new_child_prev=NULL;
3082
 
        }
3083
 
      else
3084
 
        {
3085
 
          returnval->new_child_next->new_child_prev=returnval->new_child_prev;
3086
 
          returnval->new_child_prev->new_child_next=returnval->new_child_next;
3087
 
        }
3088
 
 
3089
 
      //Now link it in to the list of connected children
3090
 
      if (parent->connected_children)
3091
 
        {
3092
 
          returnval->connected_child_next=parent->connected_children;
3093
 
          returnval->connected_child_prev=
3094
 
            parent->connected_children->connected_child_prev;
3095
 
          returnval->connected_child_prev->connected_child_next=returnval;
3096
 
          returnval->connected_child_next->connected_child_prev=returnval;
3097
 
        }
3098
 
      else
3099
 
        {
3100
 
          parent->connected_children=returnval;
3101
 
          returnval->connected_child_next=returnval;
3102
 
          returnval->connected_child_prev=returnval;
3103
 
        }
3104
 
 
3105
 
      //Return the new socket
3106
 
      return returnval;
3107
 
    }
3108
 
 
3109
 
  //No new connection
3110
 
  return NULL;
3111
 
}
3112
 
 
3113
 
//If the socket has just connected (fairly useless, legacy now)
3114
 
int socket_just_connected(socketbuf *sock)
3115
 
{
3116
 
  if (sock->flags & SOCKET_DELAYED_NOW_CONNECTED)
3117
 
    {
3118
 
      sock->flags &=~ SOCKET_DELAYED_NOW_CONNECTED;
3119
 
      return 1;
3120
 
    }
3121
 
 
3122
 
  return 0;
3123
 
}
3124
 
 
3125
 
//Return the portnumber
3126
 
int socket_get_port(socketbuf *sock)
3127
 
{
3128
 
  return sock->port;
3129
 
}
3130
 
 
3131
 
#ifdef DEBUG
3132
 
//Set debug mode on or off
3133
 
void socket_debug_off(socketbuf *sock)
3134
 
{
3135
 
  sock->debug=0;
3136
 
}
3137
 
void socket_debug_on(socketbuf *sock)
3138
 
{
3139
 
  sock->debug=1;
3140
 
}
3141
 
#endif
3142
 
 
3143
 
//Return the time the socket connected
3144
 
time_t socket_connecttime(socketbuf *sock)
3145
 
{
3146
 
  return sock->connect_time;
3147
 
}
3148
 
 
3149
 
//Set a flag into the sockets mode. The only flag right now is sequential
3150
 
//and only applies to 2 way UDP sockets
3151
 
int socket_mode_set(socketbuf *sock,unsigned int mode)
3152
 
{
3153
 
  sock->mode|=mode;
3154
 
  return 1;
3155
 
}
3156
 
 
3157
 
//Remove a flag from a socket
3158
 
int socket_mode_unset(socketbuf *sock,unsigned int mode)
3159
 
{
3160
 
  sock->mode&=~mode;
3161
 
  return 1;
3162
 
}
3163
 
 
3164
 
//Get the sockets mode
3165
 
unsigned int socket_mode_get(socketbuf *sock)
3166
 
{
3167
 
  return sock->mode;
3168
 
}
3169
 
 
3170
 
const char *socket_host_get(socketbuf *sock)
3171
 
{
3172
 
  return sock->host;
3173
 
}
3174
 
 
3175
 
#ifdef SOCK_SSL
3176
 
 
3177
 
void socket_set_encrypted(socketbuf *sock)
3178
 
{
3179
 
  static int ssl_initialised=0;
3180
 
 
3181
 
  if (!ssl_initialised)
3182
 
    {
3183
 
      ssl_initialised=1;
3184
 
      SSL_library_init();
3185
 
      SSL_load_error_strings();
3186
 
    }
3187
 
 
3188
 
  sock->encrypted=2;
3189
 
  if (sock->flags & SOCKET_LISTENER)
3190
 
    socket_set_listener_encrypted(sock);
3191
 
  else if (sock->flags & SOCKET_INCOMING)
3192
 
    socket_set_server_encrypted(sock);
3193
 
  else
3194
 
    socket_set_client_encrypted(sock);
3195
 
}
3196
 
 
3197
 
 
3198
 
void socket_set_server_key(socketbuf *sock,const char *keyfile)
3199
 
{
3200
 
  sock->server_key_file=(char *)malloc(strlen(keyfile)+1);
3201
 
  strcpy(sock->server_key_file,keyfile);
3202
 
}
3203
 
 
3204
 
void socket_set_server_cert(socketbuf *sock,const char *certfile)
3205
 
{
3206
 
  sock->server_cert_file=(char *)malloc(strlen(certfile)+1);
3207
 
  strcpy(sock->server_cert_file,certfile);
3208
 
}
3209
 
 
3210
 
void socket_set_client_ca(socketbuf *sock,const char *cafile)
3211
 
{
3212
 
  sock->client_ca_file=(char *)malloc(strlen(cafile)+1);
3213
 
  strcpy(sock->client_ca_file,cafile);
3214
 
}
3215
 
 
3216
 
#endif //SOCK_SSL
3217
 
 
3218
 
//This moves the buffers from one socket to another, MOVING it, not
3219
 
//copying it. This is not a simple task as it needs to take into
3220
 
//account all buffers in the UDP resend queue to!
3221
 
void socket_relocate_data(socketbuf *from,socketbuf *to)
3222
 
{
3223
 
  socket_udp_rdata *scan,*target;
3224
 
 
3225
 
  //Transfer data in the resend queue to the new out queue. Do this first so it
3226
 
  //goes back out in order
3227
 
  while (from->udp2w_rdata_out)
3228
 
    {
3229
 
      scan=from->udp2w_rdata_out;
3230
 
      target=scan;
3231
 
      while (scan)
3232
 
        {
3233
 
          if (scan->packetnum < target->packetnum)
3234
 
            target=scan;
3235
 
          scan=scan->next;
3236
 
          if (scan==from->udp2w_rdata_out)
3237
 
            scan=NULL;
3238
 
        }
3239
 
 
3240
 
      //Add this data to the out queue
3241
 
      socket_write_reliable(to,
3242
 
                            target->data,target->length);
3243
 
 
3244
 
      //Now unlink that target
3245
 
      from->udp2w_rdata_out=socket_rdata_delete(from->udp2w_rdata_out,target);
3246
 
    }
3247
 
 
3248
 
 
3249
 
  //Transfer the old outqueue to the new outqueue
3250
 
  dynstringRawappend(to->outdata,(char *)(from->outdata->buf),from->outdata->len);
3251
 
  from->outdata->len=0;
3252
 
 
3253
 
  //Transfer any unread inqueue to the new inqueue
3254
 
  dynstringRawappend(to->indata,(char *)(from->indata->buf),from->indata->len);
3255
 
  from->indata->len=0;
3256
 
 
3257
 
  //We're done
3258
 
  return;
3259
 
}
3260
 
 
3261
 
 
3262
 
/****************************************************************************
3263
 
 **                Extention for 2-way and reliable UDP                    **
3264
 
 ** This is NOT generally compatable, you need to run this socket code     **
3265
 
 ** at both ends                                                           **
3266
 
 ****************************************************************************/
3267
 
 
3268
 
//Send the connection message to a remote listener. This initialises the
3269
 
//session
3270
 
int socket_udp2way_connectmessage(socketbuf *sock)
3271
 
{
3272
 
  int written;
3273
 
  int datalen;
3274
 
  socket_intchar intval;
3275
 
  char buf[HOST_NAME_MAX+60+1+12];
3276
 
 
3277
 
  //Now we construct new data to send
3278
 
  //Data is as follows:
3279
 
 
3280
 
  //4 bytes: Protocol
3281
 
  //4 bytes: Local portnumber
3282
 
  //4 bytes: The length of the unique identifier string
3283
 
  //       : The unique identifier string
3284
 
  //
3285
 
 
3286
 
  intval.i=htonl(SOCKET_UDP2W_PROTOCOL_CONNECTION);
3287
 
  memcpy(buf,intval.c,4);
3288
 
 
3289
 
  intval.i=htonl(sock->udp2w_port);
3290
 
  memcpy(buf+4,intval.c,4);
3291
 
 
3292
 
  datalen=strlen(sock->udp2w_unique);
3293
 
  intval.i=htonl(datalen);
3294
 
  memcpy(buf+8,intval.c,4);
3295
 
 
3296
 
  memcpy(buf+12,sock->udp2w_unique,datalen);
3297
 
 
3298
 
  //Send the data to the socket
3299
 
  written=sendto(sock->fd,
3300
 
                 buf,12+datalen,
3301
 
                 MSG_DONTWAIT,
3302
 
                 (struct sockaddr *)&sock->udp_sa,
3303
 
                 sizeof(struct sockaddr_in));
3304
 
 
3305
 
  if (written==-1)
3306
 
    {
3307
 
      if (errno!=EAGAIN)
3308
 
        {
3309
 
          //If the error is not EAGAIN, its dead
3310
 
          sock->flags |= SOCKET_DEAD;
3311
 
          return 0;
3312
 
        }
3313
 
    }
3314
 
 
3315
 
  //Return the number of bytes sent
3316
 
  return written;
3317
 
}
3318
 
 
3319
 
 
3320
 
//This is sent as a reply, the connectmessage has been received, now we need to
3321
 
//acknowledge it
3322
 
static int socket_udp2way_connectmessage_reply(socketbuf *sock)
3323
 
{
3324
 
  int written;
3325
 
  socket_intchar val;
3326
 
  char buf[4];
3327
 
 
3328
 
  //Now we construct new data to send
3329
 
  //4 bytes : protocol
3330
 
 
3331
 
  val.i=htonl(SOCKET_UDP2W_PROTOCOL_CONNECTION);
3332
 
  memcpy(buf,val.c,4);
3333
 
 
3334
 
  //Send the data
3335
 
  written=sendto(sock->fd,
3336
 
                 buf,4,
3337
 
                 MSG_DONTWAIT,
3338
 
                 (struct sockaddr *)&sock->udp_sa,
3339
 
                 sizeof(struct sockaddr_in));
3340
 
 
3341
 
  if (written==-1)
3342
 
    {
3343
 
      if (errno!=EAGAIN)
3344
 
        {
3345
 
          //This is a fatal error, kill the socket
3346
 
          sock->flags |= SOCKET_DEAD;
3347
 
          return 0;
3348
 
        }
3349
 
    }
3350
 
 
3351
 
  return written;
3352
 
}
3353
 
 
3354
 
 
3355
 
//This function creates a 2 way UDP socket connection to a remote host
3356
 
socketbuf *socket_create_inet_udp2way_wait(const char *host,int port,int wait)
3357
 
{
3358
 
  socketbuf *sock,*insock;
3359
 
  int inport;
3360
 
  struct timeval time_now;
3361
 
  char hostname[HOST_NAME_MAX+1];
3362
 
 
3363
 
  //Simply - we create a socket outbound
3364
 
  sock=socket_create_inet_udp_wait(host,port,wait);
3365
 
 
3366
 
  if (!sock)
3367
 
    return 0;
3368
 
 
3369
 
  //Now create a listener, NOT on the same port but on a port that is
3370
 
  //as close as we can make it. We dont do it on the same port as it is
3371
 
  //possible that in a failover condition, the main socket may be bound
3372
 
  //later, causing inability to failover servers
3373
 
  insock=NULL;
3374
 
  inport=port;
3375
 
  while (!insock)
3376
 
    {
3377
 
      inport++;
3378
 
      //Create a listener on the new socket
3379
 
      insock=socket_create_inet_udp_listener(inport);
3380
 
    }
3381
 
 
3382
 
 
3383
 
  //We now have 2 socketbufs, but we really only want one - lets take the
3384
 
  //actual inbound socket and put it in the first sockets data, then kill 
3385
 
  //the second set of data
3386
 
 
3387
 
  sock->udp2w_infd=insock->fd;
3388
 
  sock->udp2w_port=inport;
3389
 
 
3390
 
  sock->udp2w=1;
3391
 
  sock->udp2w_averound=2500000; /*Set it for a sloooooow network, it will 
3392
 
                                  modify itself if the network shows it is
3393
 
                                  faster*/
3394
 
  sock->udp2w_lastmsg=time(NULL);
3395
 
 
3396
 
  insock->fd=0;
3397
 
 
3398
 
  //Get rid of the unused listener data struct
3399
 
  socket_destroy(insock);
3400
 
 
3401
 
  sock->flags|=SOCKET_CONNECTING;
3402
 
  sock->flags&=~SOCKET_CONNECTED;
3403
 
  //Send the init data
3404
 
 
3405
 
  //We CANNOT wait for the response, or it will never get there if the
3406
 
  //client and server run on the same thread
3407
 
 
3408
 
  //Now we set a unique value, as we use UDP, so the other side knows WHO
3409
 
  //is connecting
3410
 
  gethostname(hostname,HOST_NAME_MAX);
3411
 
 
3412
 
  gettimeofday(&time_now,NULL);
3413
 
 
3414
 
  //Create a unique name for this client. This will be unique anywhere unless
3415
 
  //you have 2 connections on the same machine in the same microsecond. Pretty
3416
 
  //fullproof I reckon
3417
 
  sprintf(sock->udp2w_unique,"%s-%ld.%ld",hostname,
3418
 
          time_now.tv_sec,time_now.tv_usec);
3419
 
 
3420
 
  //Send the connect protocol message to the remote server
3421
 
  socket_udp2way_connectmessage(sock);
3422
 
 
3423
 
  return sock;
3424
 
}
3425
 
 
3426
 
//Create the 2 way listener on a specific IP address
3427
 
socketbuf *socket_create_inet_udp2way_listener_on_ip(const char *localip,
3428
 
                                                     int port)
3429
 
{
3430
 
  socketbuf *sock;
3431
 
 
3432
 
  //Create the basic UDP listener
3433
 
  sock=socket_create_inet_udp_listener_on_ip(localip,port);
3434
 
 
3435
 
  //All we do extra is the 2 way UDP specific values
3436
 
  if (sock)
3437
 
    {
3438
 
      sock->udp2w=1;
3439
 
      sock->udp2w_averound=2500000;
3440
 
      sock->udp2w_lastmsg=time(NULL);
3441
 
    }
3442
 
 
3443
 
  return sock;
3444
 
}
3445
 
 
3446
 
//Wrapper function, to set a 2 way UDP listener bound to all interfaces
3447
 
socketbuf *socket_create_inet_udp2way_listener(int port)
3448
 
{
3449
 
  return socket_create_inet_udp2way_listener_on_ip(NULL,port);
3450
 
}
3451
 
 
3452
 
//This function takes a bit of explaining.
3453
 
//UDP always sends data to the 'listener' socket, not to a socket specific to
3454
 
//the user. This means that all data comes in to the one socket and then needs
3455
 
//to be associated with a socket for THAT user
3456
 
//So, each packet contains the IP address and the portnumber of the sender
3457
 
//which allows unique identification. This function looks at all sockets
3458
 
//that are children of the listener, and finds the one that matches the host
3459
 
//and the portnumber of the sender.
3460
 
static socketbuf *socket_get_child_socketbuf(socketbuf *sock,
3461
 
                                             char *host,int port)
3462
 
{
3463
 
  socketbuf *scan;
3464
 
 
3465
 
  scan=sock->new_children;
3466
 
  while (scan)
3467
 
    {
3468
 
      if (!strcmp(scan->host,host) && scan->port==port && !socket_dead(scan))
3469
 
        return scan;
3470
 
      scan=scan->new_child_next;
3471
 
      if (scan==sock->new_children)
3472
 
        scan=NULL;
3473
 
    }
3474
 
 
3475
 
  scan=sock->connected_children;
3476
 
  while (scan)
3477
 
    {
3478
 
      if (!strcmp(scan->host,host) && scan->port==port && !socket_dead(scan))
3479
 
        return scan;
3480
 
      scan=scan->connected_child_next;
3481
 
      if (scan==sock->connected_children)
3482
 
        scan=NULL;
3483
 
    }
3484
 
 
3485
 
  return NULL;
3486
 
}
3487
 
 
3488
 
//This works in the same way as above, but instead of using the
3489
 
//hostname it uses the sockaddr_in function as its host comparison. It
3490
 
//works in the same way but is slightly quicker as it uses an integer
3491
 
//== operation instead of a strcmp
3492
 
static socketbuf *socket_get_child_socketbuf_sa(socketbuf *sock,
3493
 
                                                struct sockaddr_in *sa,
3494
 
                                                int port)
3495
 
{
3496
 
  socketbuf *scan;
3497
 
 
3498
 
  scan=sock->new_children;
3499
 
  while (scan)
3500
 
    {
3501
 
      if (scan->udp_sa.sin_addr.s_addr==sa->sin_addr.s_addr &&
3502
 
          scan->port==port && !socket_dead(scan))
3503
 
        return scan;
3504
 
 
3505
 
      scan=scan->new_child_next;
3506
 
      if (scan==sock->new_children)
3507
 
        scan=NULL;
3508
 
    }
3509
 
 
3510
 
  scan=sock->connected_children;
3511
 
  while (scan)
3512
 
    {
3513
 
      if (scan->udp_sa.sin_addr.s_addr==sa->sin_addr.s_addr &&
3514
 
          scan->port==port && !socket_dead(scan))
3515
 
        return scan;
3516
 
      scan=scan->connected_child_next;
3517
 
      if (scan==sock->connected_children)
3518
 
        scan=NULL;
3519
 
    }
3520
 
 
3521
 
  return NULL;
3522
 
}
3523
 
 
3524
 
//This function is called when a 2 way UDP connection is received. This
3525
 
//means that we need to find out if we are already connected, and then
3526
 
//connect back to them if we arent. We must also allow for the fact that
3527
 
//someone may reconnect when we THINK they are already connected
3528
 
static socketbuf *socket_udp2way_listener_create_connection(socketbuf *sock,
3529
 
                                                            struct sockaddr_in *sa,
3530
 
                                                            size_t sa_len,
3531
 
                                                            int port,
3532
 
                                                            char *unique)
3533
 
{
3534
 
  int fd,dummy;
3535
 
  socketbuf *returnval,*oldreturnval;
3536
 
  char host[20];
3537
 
#ifndef FIONBIO
3538
 
# ifdef O_NONBLOCK
3539
 
  int flags;
3540
 
# endif
3541
 
#endif
3542
 
 
3543
 
  //Create an outgoing socket back to the originator
3544
 
 
3545
 
  //Find their IP address
3546
 
  inet_ntop(AF_INET,(void *)(&sa->sin_addr),host,19);
3547
 
 
3548
 
  //Find if anyone else is connected to this listener from that port
3549
 
  returnval=socket_get_child_socketbuf(sock,host,port);
3550
 
 
3551
 
 
3552
 
  //Note if we have no match already connected, this whole loop will not
3553
 
  //start
3554
 
  oldreturnval=0;
3555
 
  while (returnval && returnval!=oldreturnval)
3556
 
    {
3557
 
      //We loop here onthe highly unlikely chance we already have 2
3558
 
      //connections from the same port. This is impossible but just in case,
3559
 
      //its a negligable overhead to be sure
3560
 
 
3561
 
      oldreturnval=returnval;
3562
 
      /*First, check if we are already connected to THIS one*/
3563
 
 
3564
 
      if (returnval->udp2w_unique && strcmp(returnval->udp2w_unique,unique))
3565
 
        {
3566
 
          //This is a different one, mark THAT one as dead, cos we cant 
3567
 
          //have 2 sockets coming from the same place, its impossible. The old
3568
 
          //one must be dead
3569
 
          returnval->flags |= SOCKET_DEAD;
3570
 
        }
3571
 
      returnval=socket_get_child_socketbuf(sock,host,port);
3572
 
    }
3573
 
 
3574
 
  //We have no match, so we create a new outbound. NOTE: this means if the same
3575
 
  //connection was made more than once, the socket is not duplicated
3576
 
  if (!returnval)
3577
 
    {
3578
 
      //Create the socket
3579
 
      fd=socket(PF_INET,SOCK_DGRAM,IPPROTO_IP);
3580
 
      if (fd<1)
3581
 
        //No socket, no way to procede
3582
 
        return 0;
3583
 
 
3584
 
      //Create the socketbuf around the fd
3585
 
      returnval=socket_create(fd);
3586
 
      
3587
 
      //Set the udp_sa so we have an identifier for the other end
3588
 
      memset(&returnval->udp_sa,0,sizeof(struct sockaddr_in));
3589
 
      
3590
 
      //Set the destination
3591
 
      returnval->udp_sa.sin_family=AF_INET;
3592
 
      returnval->udp_sa.sin_port=htons(port);
3593
 
      returnval->udp_sa.sin_addr.s_addr=sa->sin_addr.s_addr;
3594
 
      
3595
 
      //Set the 2 way UDP stuff
3596
 
      returnval->protocol=SOCKET_UDP;
3597
 
      returnval->udp2w=1;
3598
 
      returnval->udp2w_averound=2500000;
3599
 
      returnval->udp2w_lastmsg=time(NULL);
3600
 
      strcpy(returnval->udp2w_unique,unique);
3601
 
      
3602
 
      returnval->mode=sock->mode;
3603
 
 
3604
 
      //Record the hostname too
3605
 
      returnval->host=(char *)malloc(strlen(host)+1);
3606
 
      strcpy(returnval->host,host);
3607
 
      
3608
 
      returnval->port=port;
3609
 
      
3610
 
      //Set non-blocking, so we can check for a data without freezing
3611
 
      
3612
 
#ifdef FIONBIO
3613
 
      dummy=1;
3614
 
      
3615
 
      if (ioctl(fd,FIONBIO,&dummy)<0)
3616
 
        {
3617
 
          close(fd);
3618
 
      return 0;
3619
 
        }
3620
 
#else
3621
 
#  ifdef O_NONBLOCK
3622
 
      flags=fcntl(fd,F_GETFL,0);
3623
 
      
3624
 
      if (flags<0)
3625
 
        {
3626
 
          close(fd);
3627
 
          return 0;
3628
 
        }
3629
 
      
3630
 
      if (fcntl(fd,F_SETFL,flags|O_NONBLOCK)<0)
3631
 
        {
3632
 
          close(fd);
3633
 
          return 0;
3634
 
        }
3635
 
      
3636
 
# else
3637
 
#  error No valid non-blocking method - cannot build;
3638
 
# endif // O_NONBLOCK
3639
 
#endif //FIONBIO
3640
 
      
3641
 
 
3642
 
      //Set the flags to connected
3643
 
      returnval->flags |= (SOCKET_CONNECTED|SOCKET_INCOMING);
3644
 
      
3645
 
      returnval->parent=sock;
3646
 
 
3647
 
      //Link this in to the new children list as it needs to be acknowledged
3648
 
      //by the calling program
3649
 
      if (sock->new_children)
3650
 
        {
3651
 
          returnval->new_child_next=sock->new_children;
3652
 
          returnval->new_child_prev=returnval->new_child_next->new_child_prev;
3653
 
          returnval->new_child_next->new_child_prev=returnval;
3654
 
          returnval->new_child_prev->new_child_next=returnval;
3655
 
        }
3656
 
      else
3657
 
        {
3658
 
          returnval->new_child_next=returnval;
3659
 
          returnval->new_child_prev=returnval;
3660
 
          sock->new_children=returnval;
3661
 
        }
3662
 
 
3663
 
      returnval->connect_time=time(NULL);
3664
 
    }
3665
 
 
3666
 
  //Send the reply to acknowledge the connection
3667
 
  socket_udp2way_connectmessage_reply(returnval);
3668
 
  
3669
 
  return returnval;
3670
 
}
3671
 
 
3672
 
//This function acknowledges the sending of a reliable data packet. This will
3673
 
//tell the sender that the packet has been accepted and can now be dropped.
3674
 
//If the sender does not receive this by the time the packet resend comes
3675
 
//around, the packet will be resent.
3676
 
static int socket_acknowledge_listener_udp_rpacket(socketbuf *sock,
3677
 
                                                   int packetnumber)
3678
 
{
3679
 
  int written;
3680
 
  socket_intchar intval;
3681
 
  char buf[8];
3682
 
 
3683
 
  //Now we construct new data to send
3684
 
 
3685
 
  //4 bytes: Protocol
3686
 
  //4 bytes: Packet number
3687
 
 
3688
 
  intval.i=htonl(SOCKET_UDP2W_PROTOCOL_RCONFIRM);
3689
 
  memcpy(buf,intval.c,4);
3690
 
 
3691
 
  intval.i=htonl(packetnumber);
3692
 
  memcpy(buf+4,intval.c,4);
3693
 
 
3694
 
  //Send to the socket
3695
 
  written=sendto(sock->fd,
3696
 
                 buf,8,
3697
 
                 MSG_DONTWAIT,
3698
 
                 (struct sockaddr *)&sock->udp_sa,
3699
 
                 sizeof(struct sockaddr_in));
3700
 
 
3701
 
  if (written==-1)
3702
 
    {
3703
 
      if (errno!=EAGAIN)
3704
 
        {
3705
 
          //If the send fails, the socket dies
3706
 
          sock->flags |= SOCKET_DEAD;
3707
 
          return 0;
3708
 
        }
3709
 
    }
3710
 
 
3711
 
  return written;
3712
 
}
3713
 
 
3714
 
//This function handles all incoming data sent to a listener socket
3715
 
//from a client.
3716
 
int socket_udp2way_listener_data_process(socketbuf *sock,
3717
 
                                         struct sockaddr_in *sa,
3718
 
                                         size_t sa_len,
3719
 
                                         signed char *buf,int datalen)
3720
 
{
3721
 
  socket_intchar len,val;
3722
 
  socket_udp_rdata *oldpacket,*packet;
3723
 
  socketbuf *client;
3724
 
  int type,port,packetnumber,uniquelen;
3725
 
  char unique[HOST_NAME_MAX+60+1];
3726
 
  struct timeval time_now;
3727
 
  
3728
 
  //There must always be at least 4 bytes, that is a protocol header
3729
 
  if (datalen<4)
3730
 
    return 0;
3731
 
 
3732
 
  memcpy(val.c,buf,4);
3733
 
  type=ntohl(val.i);
3734
 
 
3735
 
  //We have the protocol
3736
 
 
3737
 
  if (type==SOCKET_UDP2W_PROTOCOL_CONNECTION)
3738
 
    {
3739
 
      //New connection messages need 12 bytes minimum
3740
 
      //4 Bytes : Protocol
3741
 
      //4 Bytes : Port number
3742
 
      //4 Bytes : Length of the unique identifier
3743
 
      //        : Unique identifier
3744
 
 
3745
 
      if (datalen<12)
3746
 
        return 0;
3747
 
      memcpy(val.c,buf+4,4);
3748
 
 
3749
 
      //Now get the unique connection ID that we have
3750
 
      memcpy(len.c,buf+8,4);
3751
 
      uniquelen=ntohl(len.i);
3752
 
      memcpy(unique,buf+12,uniquelen);
3753
 
      unique[uniquelen]=0;
3754
 
 
3755
 
      //Now call the creat connection function to handle this message
3756
 
      socket_udp2way_listener_create_connection(sock,sa,sa_len,ntohl(val.i),
3757
 
                                                unique);
3758
 
      
3759
 
      return 1;
3760
 
    }
3761
 
 
3762
 
  if (type==SOCKET_UDP2W_PROTOCOL_DATA
3763
 
      )
3764
 
    {
3765
 
      //This is user data, it is NOT reliable so we just take it and use
3766
 
      //it
3767
 
 
3768
 
      // 4 bytes : protocol
3769
 
      // 4 bytes : originating port
3770
 
      //         : data
3771
 
 
3772
 
      //This doesnt go on the listeners inbound, it goes on the clients
3773
 
 
3774
 
      //Get the port as the next byte
3775
 
      memcpy(val.c,buf+4,4);
3776
 
      port=ntohl(val.i);
3777
 
 
3778
 
      //Locate the client from the ones connected to this listener
3779
 
      client=socket_get_child_socketbuf_sa(sock,sa,port);
3780
 
      if (client)
3781
 
        {
3782
 
          //Note that this client has received a message - helps timeouts
3783
 
          client->udp2w_lastmsg=time(NULL);
3784
 
 
3785
 
          //Store the data in this clients incoming data stream
3786
 
          len.i=datalen-8;
3787
 
          dynstringRawappend(client->indata,len.c,4);
3788
 
          dynstringRawappend(client->indata,(char *)buf+8,datalen-8);
3789
 
        }
3790
 
      return 1;
3791
 
    }
3792
 
 
3793
 
  if (type==SOCKET_UDP2W_PROTOCOL_RDATA 
3794
 
      )
3795
 
    {
3796
 
      //This is a RELIABLE data packet and requires handling specially
3797
 
 
3798
 
      // 4 bytes : protocol
3799
 
      // 4 bytes : originating port
3800
 
      // 4 bytes : packet number
3801
 
      //         : data
3802
 
 
3803
 
 
3804
 
      //This doesnt go on the listeners inbound, it goes on the clients
3805
 
      if (datalen<8)
3806
 
        return 0;
3807
 
 
3808
 
      //Get the port as the next byte
3809
 
      memcpy(val.c,buf+4,4);
3810
 
      port=ntohl(val.i);
3811
 
 
3812
 
      //Locate the client associated with this message
3813
 
      client=socket_get_child_socketbuf_sa(sock,sa,port);
3814
 
      if (client)
3815
 
        {
3816
 
          //Note that this client has received a message - helps timeouts
3817
 
          client->udp2w_lastmsg=time(NULL);
3818
 
 
3819
 
          //get the packet number
3820
 
          memcpy(val.c,buf+8,4);
3821
 
          packetnumber=ntohl(val.i);
3822
 
 
3823
 
          //The packet number is important. The packets may need to be
3824
 
          //stored in sequence. It may also be a packet we have had before,
3825
 
          //as the acknowledgement does not always make it back.
3826
 
 
3827
 
          //We have in the socketbuf the next packet number we are expecting,
3828
 
          //all packets earlier than this have been processed and forgotten
3829
 
 
3830
 
          
3831
 
          if (packetnumber==client->udp2w_rinpacket)
3832
 
            {
3833
 
              client->udp2w_rinpacket++;
3834
 
              //Its the correct next packet - we can just send it to the buffer
3835
 
              len.i=datalen-12;
3836
 
              dynstringRawappend(client->indata,len.c,4);
3837
 
              dynstringRawappend(client->indata,(char *)buf+12,
3838
 
                                   datalen-12);
3839
 
            }
3840
 
          else if (packetnumber<client->udp2w_rinpacket)
3841
 
            {
3842
 
              //We've already got this one, ignore it
3843
 
            }
3844
 
          else if (socket_rdata_locate_packetnum(client->udp2w_rdata_in,
3845
 
                                                 packetnumber))
3846
 
            {
3847
 
              //This packet is one we have received and wating to be processed
3848
 
            }
3849
 
          else
3850
 
            {
3851
 
              //This is one we dont have yet, and we also dont have its
3852
 
              //predecessor, 
3853
 
              //There are 2 ways to handle this:
3854
 
              // 1) Sequential mode: 
3855
 
              //      We add it onto a queue and wait for the previous ones
3856
 
              // 2) Non-sequential mode:
3857
 
              //      We deal with it now, but add it to the list anyway, so
3858
 
              //      we know its been dealt with.
3859
 
              if (!(client->mode & SOCKET_MODE_UDP2W_SEQUENTIAL))
3860
 
                {
3861
 
                  //We store the packet, we note that it HAS been sent, so we
3862
 
                  //can switch between sequential and non-sequential modes
3863
 
                  //without losing track of the packets we've already processed
3864
 
                  client->udp2w_rdata_in=rdata_allocate(client->udp2w_rdata_in,
3865
 
                                                        packetnumber,
3866
 
                                                        (char *)(buf+12),
3867
 
                                                        datalen-12,1);
3868
 
 
3869
 
                  //We arent sequential, so we just send it to the out buffer
3870
 
                  len.i=datalen-12;
3871
 
                  dynstringRawappend(client->indata,len.c,4);
3872
 
                  dynstringRawappend(client->indata,(char *)buf+12,
3873
 
                                       datalen-12);
3874
 
                }
3875
 
              else
3876
 
                //We are sequential, so all we do is add it to the list for
3877
 
                //later handling
3878
 
                client->udp2w_rdata_in=rdata_allocate(client->udp2w_rdata_in,
3879
 
                                                      packetnumber,
3880
 
                                                      (char *)(buf+12),
3881
 
                                                      datalen-12,0);
3882
 
            }
3883
 
 
3884
 
          //we may have now got a series of packets we can send, or at least
3885
 
          //get rid of. So, we test this.
3886
 
 
3887
 
          //Check the next accepted packet is not on the received list
3888
 
          oldpacket=socket_rdata_locate_packetnum(client->udp2w_rdata_in,
3889
 
                                                  client->udp2w_rinpacket);
3890
 
          while (oldpacket)
3891
 
            {
3892
 
              if (oldpacket->sent)
3893
 
                {
3894
 
                  //We are sequential, so this hasnt been sent yet
3895
 
                  len.i=oldpacket->length;
3896
 
                  dynstringRawappend(client->indata,len.c,4);
3897
 
                  dynstringRawappend(client->indata,oldpacket->data,
3898
 
                                       oldpacket->length);
3899
 
                }
3900
 
 
3901
 
              //Now its 'in the past' delete it
3902
 
              client->udp2w_rdata_in=
3903
 
                socket_rdata_delete(client->udp2w_rdata_in,
3904
 
                                    oldpacket);
3905
 
              
3906
 
              //Incriment the packet number
3907
 
              client->udp2w_rinpacket++;
3908
 
 
3909
 
              //try the next!
3910
 
              oldpacket=socket_rdata_locate_packetnum(client->udp2w_rdata_in,
3911
 
                                                      client->udp2w_rinpacket);
3912
 
            }
3913
 
 
3914
 
          //acknowledge the packet we have just received
3915
 
          socket_acknowledge_listener_udp_rpacket(client,packetnumber);
3916
 
        }
3917
 
      
3918
 
      return 1;
3919
 
    }
3920
 
  
3921
 
  if (type==SOCKET_UDP2W_PROTOCOL_RCONFIRM
3922
 
      )
3923
 
    {
3924
 
      //This is the confirmation of a packet we sent in reliable mode
3925
 
 
3926
 
      // 4 bytes : protocol
3927
 
      // 4 bytes : priginating port
3928
 
      // 4 bytes : packet number
3929
 
 
3930
 
      //This doesnt confirm on the listeners port, but on the clients
3931
 
      if (datalen<8)
3932
 
        return 0;
3933
 
      
3934
 
      //Get the port as the next byte
3935
 
      memcpy(val.c,buf+4,4);
3936
 
      port=ntohl(val.i);
3937
 
 
3938
 
      //Locate the client associated with this
3939
 
      client=socket_get_child_socketbuf_sa(sock,sa,port);
3940
 
 
3941
 
      if (client)
3942
 
        {
3943
 
          //Record their link is active
3944
 
          client->udp2w_lastmsg=time(NULL);
3945
 
 
3946
 
          //Comes with a packet number
3947
 
          memcpy(val.c,buf+8,4);
3948
 
          packetnumber=ntohl(val.i);
3949
 
 
3950
 
          //Locate this packet in the list of packets we are remembering to
3951
 
          //resend
3952
 
          packet=socket_rdata_locate_packetnum(client->udp2w_rdata_out,
3953
 
                                               packetnumber);
3954
 
 
3955
 
          if (packet)
3956
 
            {
3957
 
              //rebalance the timings for knowing when to resend
3958
 
              client->udp2w_averound=(long long)(client->udp2w_averound*0.9);
3959
 
 
3960
 
              gettimeofday(&time_now,NULL);
3961
 
 
3962
 
              client->udp2w_averound+=
3963
 
                ((time_now.tv_sec-packet->sendtime.tv_sec)*1000000);
3964
 
              client->udp2w_averound+=
3965
 
                (time_now.tv_usec-packet->sendtime.tv_usec);
3966
 
 
3967
 
 
3968
 
              //We've not already been told of the receipt, so delete it
3969
 
              client->udp2w_rdata_out=
3970
 
                socket_rdata_delete(client->udp2w_rdata_out,
3971
 
                                    packet);
3972
 
 
3973
 
 
3974
 
            }
3975
 
        }
3976
 
      return 1;
3977
 
    }
3978
 
 
3979
 
  if (type==SOCKET_UDP2W_PROTOCOL_PING)
3980
 
    {
3981
 
      //This is a ping packet, low level 'keep the socket alive' protocol
3982
 
 
3983
 
      // 4 bytes : protocol
3984
 
      // 4 bytes : originating portnumber
3985
 
 
3986
 
      if (datalen<8)
3987
 
        return 0;
3988
 
 
3989
 
      //Get the port as the next byte
3990
 
      memcpy(val.c,buf+4,4);
3991
 
      port=ntohl(val.i);
3992
 
 
3993
 
      //Find the correct client
3994
 
      client=socket_get_child_socketbuf_sa(sock,sa,port);
3995
 
 
3996
 
      if (client)
3997
 
        {
3998
 
          //Note we have received something
3999
 
          client->udp2w_lastmsg=time(NULL);
4000
 
        }
4001
 
 
4002
 
      return 1;
4003
 
    }
4004
 
 
4005
 
  return 1;
4006
 
}
4007
 
 
4008
 
//This function acknowledges the sending of a reliable data packet. This will
4009
 
//tell the sender that the packet has been accepted and can now be dropped.
4010
 
//If the sender does not receive this by the time the packet resend comes
4011
 
//around, the packet will be resent.
4012
 
static int socket_acknowledge_reader_udp_rpacket(socketbuf *sock,int packetnumber)
4013
 
{
4014
 
  int written;
4015
 
  socket_intchar intval;
4016
 
  char buf[12];
4017
 
 
4018
 
  //Now we construct new data to send
4019
 
 
4020
 
  //4 bytes: Protocol
4021
 
  //4 bytes: Our portnumber
4022
 
  //4 bytes: Packet number
4023
 
 
4024
 
  intval.i=htonl(SOCKET_UDP2W_PROTOCOL_RCONFIRM);
4025
 
  memcpy(buf,intval.c,4);
4026
 
 
4027
 
  intval.i=htonl(sock->udp2w_port);
4028
 
  memcpy(buf+4,intval.c,4);
4029
 
 
4030
 
  intval.i=htonl(packetnumber);
4031
 
  memcpy(buf+8,intval.c,4);
4032
 
 
4033
 
  //Send to the socket
4034
 
  written=sendto(sock->fd,
4035
 
                 buf,12,
4036
 
                 MSG_DONTWAIT,
4037
 
                 (struct sockaddr *)&sock->udp_sa,
4038
 
                 sizeof(struct sockaddr_in));
4039
 
 
4040
 
  if (written==-1)
4041
 
    {
4042
 
      if (errno!=EAGAIN)
4043
 
        {
4044
 
          //If the send fails, the socket dies
4045
 
          sock->flags |= SOCKET_DEAD;
4046
 
          return 0;
4047
 
        }
4048
 
    }
4049
 
 
4050
 
  return written;
4051
 
}
4052
 
 
4053
 
//This is VERY similar to the listener reading, except as the data can ONLY
4054
 
//come from the other end of THIS socket (we are the client) then we dont
4055
 
//need the portnumber
4056
 
int socket_udp2way_reader_data_process(socketbuf *sock,
4057
 
                                       signed char *buf,int datalen)
4058
 
{
4059
 
  socket_intchar len,val;
4060
 
  int type;
4061
 
  socket_udp_rdata *packet,*oldpacket;
4062
 
  int packetnumber;
4063
 
  struct timeval time_now;
4064
 
 
4065
 
  //There must always be at least 4 bytes, that is a protocol header
4066
 
  if (datalen<4)
4067
 
    return 0;
4068
 
 
4069
 
  memcpy(val.c,buf,4);
4070
 
  type=ntohl(val.i);
4071
 
 
4072
 
  //We have the protocol
4073
 
  
4074
 
  if (type==SOCKET_UDP2W_PROTOCOL_CONNECTION)
4075
 
    {
4076
 
      //The server has acknowledged our connection, no more needed, we are 
4077
 
      //connected
4078
 
 
4079
 
      sock->flags&=~SOCKET_CONNECTING;
4080
 
      sock->flags|=SOCKET_CONNECTED;
4081
 
 
4082
 
      return 1;
4083
 
    }
4084
 
 
4085
 
  if (type==SOCKET_UDP2W_PROTOCOL_DATA
4086
 
      )
4087
 
    {
4088
 
      //This is user data, it is NOT reliable so we just take it and use
4089
 
      //it
4090
 
 
4091
 
      //Add it to the users data buffer
4092
 
      len.i=datalen-4;
4093
 
      dynstringRawappend(sock->indata,len.c,4);
4094
 
      dynstringRawappend(sock->indata,(char *)buf+4,datalen-4);
4095
 
 
4096
 
      return 1;
4097
 
    }
4098
 
 
4099
 
  if (type==SOCKET_UDP2W_PROTOCOL_RDATA 
4100
 
      )
4101
 
    {
4102
 
      //This is a RELIABLE data packet and requires handling specially
4103
 
 
4104
 
      // 4 bytes : protocol
4105
 
      // 4 bytes : packet number
4106
 
      //         : data
4107
 
 
4108
 
      //Comes with a packet number
4109
 
      memcpy(val.c,buf+4,4);
4110
 
      packetnumber=ntohl(val.i);
4111
 
 
4112
 
      //The packet number is important. The packets may need to be
4113
 
      //stored in sequence. It may also be a packet we have had before,
4114
 
      //as the acknowledgement does not always make it back.
4115
 
 
4116
 
      //We have in the socketbuf the next packet number we are expecting,
4117
 
      //all packets earlier than this have been processed and forgotten
4118
 
 
4119
 
 
4120
 
      if (packetnumber==sock->udp2w_rinpacket)
4121
 
        {
4122
 
          //Its the correct next packet - we can just send it to the buffer
4123
 
 
4124
 
          sock->udp2w_rinpacket++;
4125
 
 
4126
 
          len.i=datalen-8;
4127
 
          dynstringRawappend(sock->indata,len.c,4);
4128
 
          dynstringRawappend(sock->indata,(char *)buf+8,datalen-8);
4129
 
        }
4130
 
      else if (packetnumber<sock->udp2w_rinpacket)
4131
 
        {
4132
 
          //We've already got this one, do nothing
4133
 
        }
4134
 
      else if (socket_rdata_locate_packetnum(sock->udp2w_rdata_in,
4135
 
                                             packetnumber))
4136
 
        {
4137
 
          //This is one we already have in the queue - do nothing
4138
 
        }
4139
 
      else
4140
 
        {
4141
 
          //This is one we dont have yet, and we also dont have its
4142
 
          //predecessor,
4143
 
          //There are 2 ways to handle this:
4144
 
          // 1) Sequential mode:
4145
 
          //      We add it onto a queue and wait for the previous ones
4146
 
          // 2) Non-sequential mode:
4147
 
          //      We deal with it now, but add it to the list anyway, so
4148
 
          //      we know its been dealt with.
4149
 
 
4150
 
          if (!(sock->mode & SOCKET_MODE_UDP2W_SEQUENTIAL))
4151
 
            {
4152
 
              //We store the packet, we note that it HAS been sent, so we
4153
 
              //can switch between sequential and non-sequential modes
4154
 
              //without losing track of the packets we've already processed
4155
 
              sock->udp2w_rdata_in=rdata_allocate(sock->udp2w_rdata_in,
4156
 
                                                  packetnumber,
4157
 
                                                  (char *)(buf+8),
4158
 
                                                  datalen-8,1);
4159
 
              
4160
 
              //We arent sequential, so we just send it to the out buffer
4161
 
              len.i=datalen-8;
4162
 
              dynstringRawappend(sock->indata,len.c,4);
4163
 
              dynstringRawappend(sock->indata,(char *)buf+8,datalen-8);
4164
 
            }
4165
 
          else
4166
 
            //We are sequential, so all we do is add it to the list for
4167
 
            //later handling
4168
 
            sock->udp2w_rdata_in=rdata_allocate(sock->udp2w_rdata_in,
4169
 
                                                packetnumber,
4170
 
                                                (char *)(buf+8),
4171
 
                                                datalen-8,0);
4172
 
        }
4173
 
 
4174
 
      //we may have now got a series of packets we can send, or at least
4175
 
      //get rid of. So, we test this.
4176
 
 
4177
 
      //Check the next accepted packet is not on the received list
4178
 
      oldpacket=socket_rdata_locate_packetnum(sock->udp2w_rdata_in,
4179
 
                                              sock->udp2w_rinpacket);
4180
 
      while (oldpacket)
4181
 
        {
4182
 
          if (!oldpacket->sent)
4183
 
            {
4184
 
              //We are sequential, so this hasnt been sent yet
4185
 
              len.i=oldpacket->length;
4186
 
              dynstringRawappend(sock->indata,len.c,4);
4187
 
              dynstringRawappend(sock->indata,oldpacket->data,
4188
 
                                   oldpacket->length);
4189
 
            }
4190
 
 
4191
 
          //Now its 'in the past' delete it
4192
 
          sock->udp2w_rdata_in=socket_rdata_delete(sock->udp2w_rdata_in,
4193
 
                                                   oldpacket);
4194
 
 
4195
 
          //Incriment the packet number
4196
 
          sock->udp2w_rinpacket++;
4197
 
 
4198
 
          //try the next!
4199
 
          oldpacket=socket_rdata_locate_packetnum(sock->udp2w_rdata_in,
4200
 
                                                  sock->udp2w_rinpacket);
4201
 
        }
4202
 
 
4203
 
      //acknowledge the packet we have just received
4204
 
      socket_acknowledge_reader_udp_rpacket(sock,packetnumber);
4205
 
 
4206
 
      return 1;
4207
 
    }
4208
 
 
4209
 
  if (type==SOCKET_UDP2W_PROTOCOL_RCONFIRM 
4210
 
      )
4211
 
    {
4212
 
 
4213
 
      //This is the confirmation of a packet we sent in reliable mode
4214
 
 
4215
 
      // 4 bytes : protocol
4216
 
      // 4 bytes : packet number
4217
 
 
4218
 
      //Comes with a packet number
4219
 
      memcpy(val.c,buf+4,4);
4220
 
      packetnumber=ntohl(val.i);
4221
 
 
4222
 
      //Locate this packet in the list of packets we are remembering to
4223
 
      //resend
4224
 
      packet=socket_rdata_locate_packetnum(sock->udp2w_rdata_out,
4225
 
                                           packetnumber);
4226
 
      if (packet)
4227
 
        {
4228
 
          //rebalance the timings, so we know better when to resend
4229
 
          sock->udp2w_averound=(long long)(sock->udp2w_averound*0.9);
4230
 
 
4231
 
          gettimeofday(&time_now,NULL);
4232
 
 
4233
 
          sock->udp2w_averound+=
4234
 
            ((time_now.tv_sec-packet->sendtime.tv_sec)*1000000);
4235
 
          sock->udp2w_averound+=(time_now.tv_usec-packet->sendtime.tv_usec);
4236
 
                  
4237
 
          //We've not already been told of the receipt, so delete it
4238
 
          sock->udp2w_rdata_out=socket_rdata_delete(sock->udp2w_rdata_out,
4239
 
                                                    packet);
4240
 
        }
4241
 
 
4242
 
      return 1;
4243
 
    }
4244
 
 
4245
 
  if (type==SOCKET_UDP2W_PROTOCOL_PING)
4246
 
    {
4247
 
      //This has already done its job by making something happen on the link
4248
 
 
4249
 
      return 1;
4250
 
    }
4251
 
 
4252
 
  return 1;
4253
 
}
4254