Statistics
| Branch: | Revision:

ml / transmissionHandler.c @ 2c702104

History | View | Annotate | Download (69 KB)

1
/*
2
 *          Policy Management
3
 *
4
 *          NEC Europe Ltd. PROPRIETARY INFORMATION
5
 *
6
 * This software is supplied under the terms of a license agreement
7
 * or nondisclosure agreement with NEC Europe Ltd. and may not be
8
 * copied or disclosed except in accordance with the terms of that
9
 * agreement.
10
 *
11
 *      Copyright (c) 2009 NEC Europe Ltd. All Rights Reserved.
12
 *
13
 * Authors: Kristian Beckers  <beckers@nw.neclab.eu>
14
 *          Sebastian Kiesel  <kiesel@nw.neclab.eu>
15
 *          
16
 *
17
 * NEC Europe Ltd. DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED,
18
 * INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES OF MERCHANTABILITY
19
 * AND FITNESS FOR A PARTICULAR PURPOSE AND THE WARRANTY AGAINST LATENT
20
 * DEFECTS, WITH RESPECT TO THE PROGRAM AND THE ACCOMPANYING
21
 * DOCUMENTATION.
22
 *
23
 * No Liability For Consequential Damages IN NO EVENT SHALL NEC Europe
24
 * Ltd., NEC Corporation OR ANY OF ITS SUBSIDIARIES BE LIABLE FOR ANY
25
 * DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS
26
 * OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF INFORMATION, OR
27
 * OTHER PECUNIARY LOSS AND INDIRECT, CONSEQUENTIAL, INCIDENTAL,
28
 * ECONOMIC OR PUNITIVE DAMAGES) ARISING OUT OF THE USE OF OR INABILITY
29
 * TO USE THIS PROGRAM, EVEN IF NEC Europe Ltd. HAS BEEN ADVISED OF THE
30
 * POSSIBILITY OF SUCH DAMAGES.
31
 *
32
 *     THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
33
 */
34
#include <arpa/inet.h>
35
#include <netinet/in.h>
36
#include <sys/socket.h>
37
#include <fcntl.h>
38
#include <event2/event.h>
39
#include <stdlib.h>
40
#include <unistd.h>
41
#include <stdio.h>
42
#include <stddef.h>
43
#include <stdint.h>
44
#include <string.h>
45
#include <sys/types.h>
46
#include <arpa/inet.h>
47
#include <netdb.h>
48
#include <errno.h>
49
#include <time.h>
50
#include <math.h>
51
#include "util/udpSocket.h"
52
#include "util/stun.h"
53
#include "transmissionHandler.h"
54

    
55
/*
56
 * a pointer to a libevent instance 
57
 */
58
struct event_base *base;
59

    
60
/*
61
 * define the nr of connections the messaging layer can handle 
62
 */
63
#define CONNECTBUFSIZE 10000
64
/*
65
 * define the nr of data that can be received parallel 
66
 */
67
#define RECVDATABUFSIZE 10000
68
/*
69
 * define an array for message multiplexing 
70
 */
71
#define MSGMULTIPLEXSIZE 127
72

    
73
/*
74
 * global variables 
75
 */
76
/*
77
 * define a buffer of pointers to connect structures 
78
 */
79
connect_data *connectbuf[CONNECTBUFSIZE];
80

    
81
/*
82
 * define a pointer buffer with pointers to recv_data structures 
83
 */
84
recvdata *recvdatabuf[RECVDATABUFSIZE];
85

    
86
/*
87
 * define a pointer buffer for message multiplexing 
88
 */
89
receive_data_cb recvcbbuf[MSGMULTIPLEXSIZE];
90

    
91
/*
92
 * stun server address 
93
 */
94
struct sockaddr_in stun_server;
95

    
96
/*
97
 * receive timeout 
98
 */
99
struct timeval recv_timeout;
100

    
101
/*
102
 * boolean NAT traversal successful if true 
103
 */
104
boolean NAT_traversal;
105

    
106
/*
107
 * file descriptor for local socket 
108
 */
109
evutil_socket_t socketfd;
110

    
111
/*
112
 * local socketID 
113
 */
114
socket_ID local_socketID;
115

    
116
socketID_handle loc_socketID = &local_socketID;
117

    
118
/*
119
 * callback function pointers 
120
 */
121
/*
122
 * monitoring module callbacks 
123
 */
124
get_recv_pkt_inf_cb get_Recv_pkt_inf_cb = NULL;
125
get_send_pkt_inf_cb get_Send_pkt_inf_cb = NULL;
126
set_monitoring_header_pkt_cb set_Monitoring_header_pkt_cb = NULL;
127
get_recv_data_inf_cb get_Recv_data_inf_cb = NULL;
128
get_send_data_inf_cb get_Send_data_inf_cb = NULL;
129
set_monitoring_header_data_cb set_Monitoring_header_data_cb = NULL;
130
/*
131
 * connection callbacks 
132
 */
133
receive_connection_cb receive_Connection_cb;
134
connection_failed_cb failed_Connection_cb;
135
/*
136
 * local socketID callback 
137
 */
138
receive_localsocketID_cb receive_SocketID_cb;
139

    
140
/*
141
 * boolean that defines if received data is transmitted to the upper layer 
142
 * via callback or via upper layer polling 
143
 */
144
boolean recv_data_callback;
145

    
146
/*
147
 * functions 
148
 */
149
/*
150
 * register callback functions 
151
 */
152

    
153
void register_get_recv_pkt_inf(get_recv_pkt_inf_cb recv_pkt_inf_cb)
154
{
155
        if (recv_pkt_inf_cb == NULL)
156
                printf("Register get_recv_pkt_inf_cb failed: NULL ptr  \n");
157
        else
158
                get_Recv_pkt_inf_cb = recv_pkt_inf_cb;
159
}
160

    
161
void register_get_send_pkt_inf(get_send_pkt_inf_cb send_pkt_inf_cb)
162
{
163
        if (send_pkt_inf_cb == NULL)
164
                printf("Register get_send_pkt_inf_cb: NULL ptr  \n");
165
        else
166
                get_Send_pkt_inf_cb = send_pkt_inf_cb;
167
}
168

    
169
void
170
register_set_monitoring_header_pkt_cb(set_monitoring_header_pkt_cb
171
                                      monitoring_header_pkt_cb)
172
{
173
        if (monitoring_header_pkt_cb == NULL)
174
                printf("Register set_monitoring_header_pkt_cb: NULL ptr  \n");
175
        else
176
                set_Monitoring_header_pkt_cb = monitoring_header_pkt_cb;
177
}
178

    
179
void register_get_recv_data_inf(get_recv_data_inf_cb recv_data_inf_cb)
180
{
181
        if (recv_data_inf_cb == NULL)
182
                printf("Register get_recv_data_inf_cb: NULL ptr  \n");
183
        else
184
                get_Recv_data_inf_cb = recv_data_inf_cb;
185
}
186

    
187
void register_get_send_data_inf(get_send_data_inf_cb send_data_inf_cb)
188
{
189
        if (send_data_inf_cb == NULL)
190
                printf("Register get_send_data_inf_cb: NULL ptr  \n");
191
        else
192
                get_Send_data_inf_cb = send_data_inf_cb;
193
}
194

    
195
void
196
register_set_monitoring_header_data_cb(set_monitoring_header_data_cb
197
                                       monitoring_header_data_cb)
198
{
199
        if (monitoring_header_data_cb == NULL)
200
                printf("Register set_monitoring_header_data_cb : NULL ptr  \n");
201
        else
202
        set_Monitoring_header_data_cb = monitoring_header_data_cb;
203
}
204

    
205
void register_recv_connection_cb(receive_connection_cb connection_cb)
206
{
207
        if (connection_cb == NULL)
208
                printf("Register receive_connection_cb: NULL ptr  \n");
209
        else
210
                receive_Connection_cb = connection_cb;
211
}
212

    
213
void
214
register_recv_localsocketID_cb(receive_localsocketID_cb local_socketID_cb)
215
{
216
        if (local_socketID_cb == NULL)
217
                printf("Register receive_localsocketID_cb: NULL ptr \n");
218
        else
219
        receive_SocketID_cb = local_socketID_cb;
220
}
221

    
222

    
223
void register_error_connection_cb(connection_failed_cb connection_fail)
224
{
225
        if (connection_fail == NULL)
226
                printf("Register connection_failed_cb: NULL ptr  \n");
227
        else
228
        failed_Connection_cb = connection_fail;
229
}
230

    
231

    
232
void register_recv_data_cb(receive_data_cb data_cb, unsigned char msgtype)
233
{
234

    
235
    if (msgtype > 126) {
236

    
237
        printf
238
            ("transmissionHandler: Could not register recv_data callback. Msgtype is greater then 126 \n");
239

    
240
    }
241

    
242
    if (data_cb == NULL) {
243

    
244
        printf("Register receive data callback: NUll ptr \n ");
245

    
246
    } else {
247

    
248
        recvcbbuf[msgtype] = data_cb;
249

    
250
    }
251
}
252

    
253
void
254
init_transmissionHandler(boolean recv_data_cb,
255
                         struct timeval timeout_value, const int port,
256
                         const char *ipaddr, const int stun_port,
257
                         const char *stun_ipaddr,
258
                         receive_localsocketID_cb local_socketID_cb,
259
                         void *arg)
260
{
261

    
262
    base = (struct event_base *) arg;
263
    recv_data_callback = recv_data_cb;
264
    setRecvTimeout(timeout_value);
265
    setStunServer(stun_port, stun_ipaddr);
266
    register_recv_localsocketID_cb(local_socketID_cb);
267
    create_socket(port, ipaddr);
268
}
269

    
270
/*
271
 * Sockets 
272
 */
273
/*
274
 * returns a handle to the socketID struct the ipaddr can be a null
275
 * pointer. Then all available ipaddr on the machine are choosen.
276
 */
277
void create_socket(const int port, const char *ipaddr)
278
{
279

    
280
    // int udpSocket = 0;
281
    /*
282
     * libevent2 
283
     */
284
    int i;
285

    
286
    struct sockaddr_in udpaddr;
287
    udpaddr.sin_family = AF_INET;
288
    if (ipaddr == NULL) {
289
        udpaddr.sin_addr.s_addr = htonl(INADDR_ANY);
290
    } else {
291
        udpaddr.sin_addr.s_addr = htonl(inet_addr(ipaddr));
292
    }
293
    udpaddr.sin_port = htons(port);
294
    socketaddrgen udpgen;
295
    udpgen.udpaddr = udpaddr;
296
    local_socketID.internal_addr = udpgen;
297

    
298
    socketfd = createSocket(port, ipaddr);
299

    
300
    struct event *ev;
301
    ev = event_new(base, socketfd, EV_READ | EV_PERSIST, recv_pkg, NULL);
302

    
303
    event_add(ev, NULL);
304

    
305
    /*
306
     * send the NAT traversal STUN request 
307
     */
308
    send_stun_request(socketfd, &stun_server);
309

    
310
    /*
311
     * enter a NAT traversal timeout that takes care of retransmission 
312
     */
313
    struct event *ev1;
314
    struct timeval timeout_value_NAT_traversal = { 2, 0 };
315
    ev1 = evtimer_new(base, nat_traversal_timeout, NULL);
316
    event_add(ev1, &timeout_value_NAT_traversal);
317

    
318
    NAT_traversal = false;
319

    
320
}
321

    
322
void close_socket(socketID_handle socketID)
323
{
324

    
325
    free(socketID);
326

    
327
}
328

    
329
/*
330
 * Connections 
331
 */
332
// the first socketID is the from socketID, the second one is the to
333
// socketID
334

    
335
int
336
open_connection(socketID_handle external_socketID, int *connectionID, receive_connection_cb connection_cb, void *arg)
337
{
338
        if (external_socketID == NULL) {
339
                printf("cannot open connection: one of the socketIDs is NULL \n");
340
                return 0;
341
        } 
342
        if (NAT_traversal == false) {
343
                printf("cannot open connection: NAT traversal for socketID still in progress  \n");
344
                return 0;
345
        }
346
        if (connection_cb == NULL) {
347
                printf("cannot open connection: connection_cb is NULL \n");
348
                return 0;
349
        }
350

    
351
        // include pmtu discovery
352
        pmtu pmtu_size = max;
353
        msgtypes msgtype = invite;
354
        char msgbuf[max];
355
        int i = 0;
356
        int seqnr = 0;
357
        boolean setEntry = false;
358

    
359
        // check if that connection already exist
360
        int exist = connection_exist(external_socketID);
361
        if (exist != -1) {
362
                setEntry = true;
363
                // if so check if it is ready to use
364
                int ready = get_connection_status(exist);
365
                
366
                // if so use the callback immidiatley
367
                if (ready == 0)
368
                                (connection_cb) (exist, arg);
369
                // otherwise just write the connection cb and the arg pointer
370
                // into the connection struct
371
                else {
372
                        struct receive_connection_cb_list *temp;
373
                        temp = malloc(sizeof(struct receive_connection_cb_list));
374
                        temp->next = NULL;
375
                        temp->connection_cb = connection_cb;
376
                        temp->arg = arg;
377
                        if(connectbuf[exist]->connection_last != NULL) {
378
                                connectbuf[exist]->connection_last->next = temp;
379
                                connectbuf[exist]->connection_last = temp;
380
                        } else
381
                                connectbuf[exist]->connection_last = connectbuf[i]->connection_head = temp;
382
                }
383
                *connectionID = exist;
384
                return 1;
385
        } else {
386
                // make entry in connection_establishment array
387
                for (i = 0; i < CONNECTBUFSIZE; i++) {
388
                        boolean internal_connect_ = false;
389
                        int check_ext_addr = compare_external_address_socketIDs(external_socketID, &local_socketID);
390
                        if (check_ext_addr == 0)
391
                                internal_connect_ = true;
392
                        if (connectbuf[i] == NULL) {
393
                                connectbuf[i] = (connect_data *) malloc(sizeof(connect_data));
394
                                connectbuf[i]->starttime = time(NULL);
395
                                connectbuf[i]->external_socketID = external_socketID;
396
                                connectbuf[i]->pmtutrysize = pmtu_size;
397
                                connectbuf[i]->pmtusize = pmtu_size;
398
                                connectbuf[i]->status = msgtype;
399
                                connectbuf[i]->seqnr = seqnr;
400
                                connectbuf[i]->internal_connect = internal_connect_;
401
                                /*
402
                                * timeout values for the pmtu discovery 
403
                                */
404
                                connectbuf[i]->timeout_value.tv_sec = 15;
405
                                connectbuf[i]->timeout_value.tv_usec = 0;
406
                                connectbuf[i]->connectionID = i;
407
                                *connectionID = i;
408
                                setEntry = true;
409

    
410
                                connectbuf[i]->connection_head = connectbuf[i]->connection_last = malloc(sizeof(struct receive_connection_cb_list));
411
                                connectbuf[i]->connection_last->next = NULL;
412
                                connectbuf[i]->connection_last->connection_cb = connection_cb;
413
                                connectbuf[i]->connection_last->arg = arg;
414
                                break;
415
                        }
416
                } //end of for
417
        }
418

    
419
        if (setEntry == false)
420
                printf("transmissionHandler:  Could not open connection: Connbuffer full \n ");
421

    
422
        // create and send a connection message
423
        create_conn_msg(msgbuf, pmtu_size, *connectionID, 0, &local_socketID, external_socketID, msgtype);
424
        send_conn_msg(*connectionID, msgbuf, pmtu_size);
425

    
426
        struct event *ev;
427
        ev = evtimer_new(base, pmtu_timeout_cb, (void *) connectbuf[i]);
428
        event_add(ev, &connectbuf[*connectionID]->timeout_value);
429

    
430
        return 1;
431
}
432

    
433
void close_connection(const int connectionID)
434
{
435

    
436
    // remove it from the connection array
437
    free(connectbuf[connectionID]);
438

    
439
}
440

    
441
void keep_connection_alive(const int connectionID)
442
{
443

    
444
    // to be done with the NAT traversal
445
    // send a message over the wire
446
    printf("\n");
447

    
448
}
449

    
450
int
451
send_all_data(const int connectionID, send_all_data_container * container,
452
              int nr_entries, unsigned char msgtype, send_params * sParams)
453
{
454

    
455

    
456

    
457
    if (nr_entries < 1 || nr_entries > 5) {
458

    
459
        printf
460
            ("send_all_data error: nr_enties is not between 1 and 5 \n ");
461
        return 0;
462

    
463
    } else {
464

    
465
        if (nr_entries == 1) {
466

    
467
            send_data(connectionID, container->buffer_1,
468
                      container->length_1, msgtype, sParams);
469

    
470
            return 1;
471

    
472
        } else if (nr_entries == 2) {
473

    
474
            int buflen = container->length_1 + container->length_2;
475
            char buf[buflen];
476
            memcpy(buf, container->buffer_1, container->length_1);
477
            memcpy(&buf[container->length_1], container->buffer_2,
478
                   container->length_2);
479
            send_data(connectionID, buf, buflen, msgtype, sParams);
480

    
481
            return 1;
482

    
483
        } else if (nr_entries == 3) {
484

    
485
            int buflen =
486
                container->length_1 + container->length_2 +
487
                container->length_3;
488
            char buf[buflen];
489
            memcpy(buf, container->buffer_1, container->length_1);
490
            memcpy(&buf[container->length_1], container->buffer_2,
491
                   container->length_2);
492
            memcpy(&buf[container->length_2], container->buffer_3,
493
                   container->length_3);
494
            send_data(connectionID, buf, buflen, msgtype, sParams);
495

    
496

    
497
            return 1;
498

    
499
        } else if (nr_entries == 4) {
500

    
501
            int buflen =
502
                container->length_1 + container->length_2 +
503
                container->length_3 + container->length_4;
504
            char buf[buflen];
505
            memcpy(buf, container->buffer_1, container->length_1);
506
            memcpy(&buf[container->length_1], container->buffer_2,
507
                   container->length_2);
508
            memcpy(&buf[container->length_2], container->buffer_3,
509
                   container->length_3);
510
            memcpy(&buf[container->length_3], container->buffer_4,
511
                   container->length_4);
512
            send_data(connectionID, buf, buflen, msgtype, sParams);
513

    
514
            return 1;
515

    
516
        } else {
517

    
518
            int buflen =
519
                container->length_1 + container->length_2 +
520
                container->length_3 + container->length_4 +
521
                container->length_5;
522
            char buf[buflen];
523
            memcpy(buf, container->buffer_1, container->length_1);
524
            memcpy(&buf[container->length_1], container->buffer_2,
525
                   container->length_2);
526
            memcpy(&buf[container->length_2], container->buffer_3,
527
                   container->length_3);
528
            memcpy(&buf[container->length_3], container->buffer_4,
529
                   container->length_4);
530
            memcpy(&buf[container->length_4], container->buffer_5,
531
                   container->length_5);
532
            send_data(connectionID, buf, buflen, msgtype, sParams);
533

    
534
            return 1;
535
        }
536

    
537
    }
538

    
539

    
540
}
541

    
542
/*
543
 * send an entire block of data 
544
 */
545
void
546
send_data(const int connectionID, char *sendbuf, int bufsize,
547
          unsigned char msgtype, send_params * sParams)
548
{
549

    
550
    if (sParams == NULL) {
551

    
552
        printf("send data failed: send_params is a NULL ptr \n");
553

    
554
    } else {
555

    
556
        // set the messagetype
557
        char packettype = msgtype;
558

    
559
        // get these variables from the connection
560
        socketID_handle local_socketID;
561
        socketID_handle external_socketID;
562
        int udpSocket;
563
        pmtu frag_size;
564
        int sendCounter = 0;
565
        // create some data for the monitoring header
566
        // The messaging layer header requires 13 bytes
567
        unsigned int dataID = 0;
568
        unsigned int offset = 0;
569
        unsigned int datasize = 0;
570
        /*
571
         * The monitoring header type has a range from 0 to 3
572
         * The numbers determine if a monitoring packet hader / monitoring data header is present
573
         *                                                                                   
574
         *     monitoring header type | data header | pkt header                                  
575
         *     -------------------------------------------------                        
576
         *               0            |     No      |    No                                
577
         *               1            |     Yes     |    No                               
578
         *               2            |     No      |    Yes                           
579
         *               3            |     Yes     |    Yes         
580
         */
581
        char monitoringHeaderType = 0;
582
        char monitoringPktHeader[MON_PACKET_HEADER_SIZE];
583
        char monitoringDataHeader[MON_DATA_HEADER_SIZE];
584
        int monitoring_data_header_set = 0;
585
        int monitoring_pkt_header_set = 0;
586
        int size_sendbuf_monitoring_header =
587
            bufsize + MON_DATA_HEADER_SIZE;
588
        char
589
         sendbuf_monitoring_header[size_sendbuf_monitoring_header];
590

    
591
        // a callback to the monitoring module if a data header should be
592
        // set
593
        if(set_Monitoring_header_data_cb != NULL) {
594
                send_pkt_type_and_dst_inf s_pkt_inf;
595

    
596
                s_pkt_inf.remote_socketID = connectbuf[connectionID]->external_socketID;
597
                s_pkt_inf.msgtype = msgtype;
598
                monitoring_data_header_set = (set_Monitoring_header_data_cb) (monitoringDataHeader, &s_pkt_inf);
599
        } else
600
                monitoring_data_header_set = 0;
601

    
602
        // set the monitoringHeaderType accordingly
603
        if (monitoring_data_header_set == 1) {
604
            monitoringHeaderType = 1;
605

    
606
            // increase the size of the buffer
607
            printf("transmissionHandler: set the monitoring module data header \n  ");
608
            char bufcpy[bufsize];
609
            memcpy(bufcpy, sendbuf, bufsize);
610
            printf("bufsize old: %d \n ", bufsize);
611
            memcpy(sendbuf_monitoring_header, monitoringDataHeader,
612
                   MON_DATA_HEADER_SIZE);
613
            memcpy(&sendbuf_monitoring_header[MON_DATA_HEADER_SIZE],
614
                   sendbuf, bufsize);
615

    
616
            bufsize += MON_DATA_HEADER_SIZE;
617
            sendbuf = sendbuf_monitoring_header;
618
            printf("transmissionHandler: set the monitoring module data header \n bufsize %d \n",bufsize);
619
        }
620

    
621

    
622
        if (connectionID < 0) {
623
            printf("transmissionHandler: ConnectionID does not exist \n");
624
            exit(1);
625

    
626
        }
627

    
628
        if (connectbuf[connectionID] == NULL) {
629
            printf("transmissionHandler: ConnectionID does not exist \n");
630
            exit(1);
631
        } else if (connectbuf[connectionID]->status != 2) {
632
            printf("transmissionHandler: Connection is not active \n");
633
            exit(1);
634
        }
635

    
636
        int external_connectionID =
637
            connectbuf[connectionID]->external_connectionID;
638

    
639
        external_socketID = connectbuf[connectionID]->external_socketID;
640

    
641
        int pmtusize = connectbuf[connectionID]->pmtusize;
642

    
643
        // printf("pmtusize %d \n ",pmtusize);
644

    
645
        if (monitoring_data_header_set == 1)
646
            frag_size = pmtusize - MON_PACKET_HEADER_SIZE;
647
        else
648
            frag_size = pmtusize;
649

    
650
        int messaginglayerpayloadsize = frag_size - MSGL_HEADER_SIZE;
651

    
652
        printf("..messaginglayerpayload %d \n", messaginglayerpayloadsize);
653

    
654
        udpSocket = socketfd;
655
        socketaddrgen udpgen;
656
        if (external_socketID != NULL) {
657
            udpgen = external_socketID->external_addr;
658
        } else {
659
            udpgen = external_socketID->internal_addr;
660
        }
661
        struct sockaddr_in socketaddr = udpgen.udpaddr;
662

    
663
        // set the data ID
664
        dataID = connectbuf[connectionID]->seqnr;
665
        connectbuf[connectionID]->seqnr = dataID + 1;
666
        datasize = bufsize;
667

    
668
        /*
669
         * create a buffer that contains the messaging layer header and
670
         * the payload fragment char packetbuffer[fragmentsize];
671
         * bzero(packetbuffer,fragmentsize); 
672
         */
673
        char *bufptr = NULL;
674
        bufptr = sendbuf;
675

    
676
        /*
677
         * monitoring module callback 
678
         */
679
        if(get_Send_data_inf_cb != NULL) {
680
                mon_data_inf sd_data_inf;
681

    
682
                sd_data_inf.remote_socketID = connectbuf[connectionID]->external_socketID;
683
                sd_data_inf.buffer = sendbuf;
684
                sd_data_inf.bufSize = bufsize;
685
                sd_data_inf.msgtype = msgtype;
686
                sd_data_inf.monitoringHeaderType = monitoringHeaderType;
687
                sd_data_inf.monitoringDataHeader = monitoringDataHeader;
688
                sd_data_inf.nrFragments = ceil(bufsize / messaginglayerpayloadsize);
689
                sd_data_inf.priority = sParams->priority;
690
                sd_data_inf.padding = sParams->padding;
691
                sd_data_inf.confirmation = sParams->confirmation;
692
                sd_data_inf.reliable = sParams->reliable;
693
                memset(&sd_data_inf.arrival_time, 0, sizeof(struct timeval));
694

    
695
                (get_Send_data_inf_cb) ((void *) &sd_data_inf);
696
        }
697
        /*
698
         * The sending loop aka fragmentation 
699
         */
700
        while (sendCounter < bufsize) {
701

    
702
            // printf("+++++test loopy \n");
703
            char msgbuf[pmtusize];
704
            bzero(msgbuf, pmtusize);
705
            char *msgbufptr = NULL;
706
            unsigned int netint = 0;
707

    
708
            /*
709
             * callback to the monitoring module if there is a monitoring
710
             * module header 
711
             */
712
                 if(set_Monitoring_header_pkt_cb != NULL) {
713
                        send_pkt_type_and_dst_inf s_pkt_inf_;
714

    
715
                        s_pkt_inf_.remote_socketID = connectbuf[connectionID]->external_socketID;
716
                        s_pkt_inf_.msgtype = msgtype;
717

    
718
                        monitoring_pkt_header_set = (set_Monitoring_header_pkt_cb) (monitoringPktHeader, &s_pkt_inf_);
719
                 }else
720
                        monitoring_pkt_header_set = 0;
721

    
722
            // set the monitoringHeaderType accordingly
723
            if (monitoring_pkt_header_set == 1) {
724
                        if (monitoringHeaderType == 0) {
725
                                monitoringHeaderType = 2;
726
                        } else if (monitoringHeaderType == 1) {
727
                                monitoringHeaderType = 3;
728
                        }
729
                 }
730

    
731
            msgbuf[0] = packettype;
732
            char pkttype[2];
733
            pkttype[0] = packettype;
734
            pkttype[1] = '\0';
735
            printf("transmissionHandler: the packet type is %s\n", pkttype);
736

    
737
            // enter the messaging layer integers
738
            netint = external_connectionID;
739
            msgbufptr = &msgbuf[1];
740
            memcpy(msgbufptr, &netint, 4);
741
            printf("transmissionHandler:  the connectionID of the other peer is %i\n", external_connectionID);
742

    
743
            netint = dataID;
744
            msgbufptr = &msgbuf[5];
745
            memcpy(msgbufptr, &netint, 4);
746
            printf("transmissionHandler:  the dataID is %i\n", dataID);
747

    
748
            netint = 0;
749
            netint = offset;
750
            msgbufptr = &msgbuf[9];
751
            memcpy(msgbufptr, &netint, 4);
752
            printf("transmissionHandler:  the offset is %i\n", offset);
753

    
754
            netint = 0;
755
            netint = datasize;
756
            msgbufptr = &msgbuf[13];
757
            memcpy(msgbufptr, &netint, 4);
758
            printf("transmissionHandler:  the datasize is %i\n", datasize);
759

    
760
            msgbuf[17] = monitoringHeaderType;
761
            sendCounter += messaginglayerpayloadsize;
762

    
763
            if (monitoring_pkt_header_set == 1) {
764
                        msgbufptr = &msgbuf[18];
765
                        memcpy(msgbufptr, monitoringPktHeader,
766
                               MON_PACKET_HEADER_SIZE);
767
                        int msgbufpos = MSGL_HEADER_SIZE + MON_PACKET_HEADER_SIZE;
768
                        msgbufptr = &msgbuf[msgbufpos];
769
                        memcpy(msgbufptr, bufptr, messaginglayerpayloadsize);
770
            } else {
771
                        msgbufptr = &msgbuf[MSGL_HEADER_SIZE];
772
                        memcpy(msgbufptr, bufptr, messaginglayerpayloadsize);
773
            }
774

    
775

    
776
            // check if this is the last fragment and adjust the size
777
            // accordingly
778

    
779
           int sendsize = pmtusize;
780

    
781
           if ((offset + messaginglayerpayloadsize) > datasize) {
782
                        sendsize = datasize - offset + MSGL_HEADER_SIZE;
783
                        if (monitoring_pkt_header_set == 1)
784
                                sendsize += MON_PACKET_HEADER_SIZE;
785
                }
786

    
787
                printf("sendsize is %d \n", sendsize);
788

    
789
                /* Monitoring layer callback */
790

    
791
                if(get_Send_pkt_inf_cb != NULL) {
792
                        mon_pkt_inf pkt_info;
793
                        pkt_info.remote_socketID = connectbuf[connectionID]->external_socketID;
794
                        pkt_info.buffer = msgbuf;
795
                        pkt_info.bufSize = sendsize;
796
                        pkt_info.msgtype = msgtype;
797
                        pkt_info.dataID = dataID;
798
                        pkt_info.offset = offset;
799
                        pkt_info.datasize = datasize;
800
                        pkt_info.monitoringHeaderType = monitoringHeaderType;
801
                        if (monitoringHeaderType == 2 || monitoringHeaderType == 3)
802
                                pkt_info.monitoringHeader = &msgbuf[18];
803
                        else
804
                                pkt_info.monitoringHeader = NULL;
805
                        pkt_info.ttl = -1;
806
                        memset(&(pkt_info.arrival_time),0,sizeof(struct timeval));
807

    
808
                        (get_Send_pkt_inf_cb) ((void *) &pkt_info);
809
                }
810
                sendPacket(udpSocket, msgbuf, sendsize, &socketaddr,
811
                       pmtu_error_cb_th);
812

    
813

    
814
            // increment the data offset
815
            offset += messaginglayerpayloadsize;
816
            fprintf(stderr, "transmissionHandler: Send a packet! \n");
817

    
818
            // increment the pointer of the buffer for the fragmentsize
819
            bufptr += messaginglayerpayloadsize;
820

    
821

    
822
        }
823

    
824
        printf("transmissionHandler: SENDING FINISHED \n");
825

    
826
    }
827

    
828

    
829
}
830

    
831
/*
832
 * recv data with polling 
833
 */
834
int
835
recv_data(const int connectionID, char *recvbuf, int *bufsize,
836
          recv_params * rParams)
837
{
838

    
839
    if (rParams == NULL) {
840

    
841
        printf("recv_data failed: recv_params is a NULL ptr \n ");
842
        return 0;
843

    
844
    } else {
845

    
846
        printf("transmissionhandler: recv data called \n");
847

    
848
        int i = 0;
849
        int returnValue = 0;
850
        double timeout = (double) recv_timeout.tv_sec;
851
        time_t endtime = time(NULL);
852

    
853
        for (i = 0; i < RECVDATABUFSIZE; i++) {
854

    
855
            if (recvdatabuf[i] != NULL) {
856

    
857
                if (recvdatabuf[i]->connectionID == connectionID) {
858

    
859
                    printf("transmissionhandler: recv data has entry  \n");
860

    
861
                    double timepass = difftime(endtime, recvdatabuf[i]->starttime);
862

    
863
                    // check if the specified connection has data and it
864
                    // is complete
865
                    // check the data seqnr
866
                    // if(connectionID == recvdatabuf[i]->connectionID &&
867
                    // 1 == recvdatabuf[i]->status){
868

    
869
                    if (1 == recvdatabuf[i]->status) {
870

    
871
                        // printf("transmissionHandler: recv_data set is
872
                        // complete \n" );
873

    
874
                        // printf("debud \n");
875

    
876
                        // exchange the pointers
877
                        int buffersize = 0;
878
                        buffersize = recvdatabuf[i]->bufsize;
879
                        *bufsize = buffersize;
880
                        // recvbuf = recvdatabuf[i]->recvbuf;
881

    
882
                        // printf("buffersize %d \n",buffersize);
883
                        memcpy(recvbuf, recvdatabuf[i]->recvbuf,
884
                               buffersize);
885
                        // printf(" recvbuf %s \n",recvbuf );
886

    
887
                        double nrMissFrags =
888
                            (double) recvdatabuf[i]->nrFragments /
889
                            (double) recvdatabuf[i]->recvFragments;
890
                        int nrMissingFragments = (int) ceil(nrMissFrags);
891

    
892
                        rParams->nrMissingFragments = nrMissingFragments;
893
                        rParams->nrFragments = recvdatabuf[i]->nrFragments;
894
                        rParams->msgtype = recvdatabuf[i]->msgtype;
895
                        rParams->connectionID =
896
                            recvdatabuf[i]->connectionID;
897

    
898
                        // break from the loop
899
                        // printf(" recvbuf %s \n ",recvbuf);
900

    
901
                        // double nrMissFrags =
902
                        // (double)recvdatabuf[i]->nrFragments /
903
                        // (double)recvdatabuf[i]->recvFragments;
904
                        // int nrMissingFragments =
905
                        // (int)ceil(nrMissFrags);
906

    
907
                        if(get_Recv_data_inf_cb != NULL) {
908
                                mon_data_inf recv_data_inf;
909

    
910
                                recv_data_inf.remote_socketID = connectbuf[connectionID]->external_socketID;
911
                                recv_data_inf.buffer = recvdatabuf[i]->recvbuf;
912
                                recv_data_inf.bufSize = recvdatabuf[i]->bufsize;
913
                                recv_data_inf.msgtype = recvdatabuf[i]->msgtype;
914
                                recv_data_inf.monitoringHeaderType = recvdatabuf[i]->monitoringHeaderType;
915
                                recv_data_inf.monitoringDataHeader = recvdatabuf[i]->monitoringDataHeader;
916
                                gettimeofday(&recv_data_inf.arrival_time, NULL);
917
                                recv_data_inf.firstPacketArrived = recvdatabuf[i]->firstPacketArrived;
918
                                recv_data_inf.nrMissingFragments = nrMissingFragments;
919
                                recv_data_inf.nrFragments = recvdatabuf[i]->nrFragments;
920
                                recv_data_inf.priority = false;
921
                                recv_data_inf.padding = false;
922
                                recv_data_inf.confirmation = false;
923
                                recv_data_inf.reliable = false;
924

    
925
                                // send data recv callback to monitoring module
926

    
927
                                (get_Recv_data_inf_cb) ((void *) &recv_data_inf);
928
                        }
929

    
930

    
931
                        // free the allocated memory
932
                        free(recvdatabuf[i]);
933
                        recvdatabuf[i] = NULL;
934

    
935
                        returnValue = 1;
936
                        break;
937

    
938
                    }
939

    
940
                    if (recvdatabuf[i] != NULL) {
941

    
942
                        if (timepass > timeout) {
943

    
944
                            printf("transmissionHandler: recv_data timeout called  \n");
945

    
946
                            // some data about the missing chunks should
947
                            // be added here
948
                            // exchange the pointers 
949
                            int buffersize = 0;
950
                            buffersize = recvdatabuf[i]->bufsize;
951
                            *bufsize = buffersize;
952
                            // recvbuf = recvdatabuf[i]->recvbuf;
953

    
954
                            double nrMissFrags =
955
                                (double) recvdatabuf[i]->nrFragments /
956
                                (double) recvdatabuf[i]->recvFragments;
957
                            int nrMissingFragments =
958
                                (int) ceil(nrMissFrags);
959

    
960
                            // printf(" recvbuf %s \n",recvbuf );
961

    
962
                            memcpy(recvbuf, recvdatabuf[i]->recvbuf,
963
                                   buffersize);
964

    
965
                            rParams->nrMissingFragments =
966
                                nrMissingFragments;
967
                            rParams->nrFragments =
968
                                recvdatabuf[i]->nrFragments;
969
                            rParams->msgtype = recvdatabuf[i]->msgtype;
970
                            rParams->connectionID =
971
                                recvdatabuf[i]->connectionID;
972

    
973
                                if(get_Recv_data_inf_cb != NULL) {
974
                                        mon_data_inf recv_data_inf;
975

    
976
                                        recv_data_inf.remote_socketID = connectbuf[connectionID]->external_socketID;
977
                                        recv_data_inf.buffer = recvdatabuf[i]->recvbuf;
978
                                        recv_data_inf.bufSize = recvdatabuf[i]->bufsize;
979
                                        recv_data_inf.msgtype = recvdatabuf[i]->msgtype;
980
                                        recv_data_inf.monitoringHeaderType = recvdatabuf[i]->monitoringHeaderType;
981
                                        recv_data_inf.monitoringDataHeader = recvdatabuf[i]->monitoringDataHeader;
982
                                        gettimeofday(&recv_data_inf.arrival_time, NULL);
983
                                        recv_data_inf.firstPacketArrived = recvdatabuf[i]->firstPacketArrived;
984
                                        recv_data_inf.nrMissingFragments = nrMissingFragments;
985
                                        recv_data_inf.nrFragments = recvdatabuf[i]->nrFragments;
986
                                        recv_data_inf.priority = false;
987
                                        recv_data_inf.padding = false;
988
                                        recv_data_inf.confirmation = false;
989
                                        recv_data_inf.reliable = false;
990

    
991
                                        // send data recv callback to monitoring module
992

    
993
                                        (get_Recv_data_inf_cb) ((void *) &recv_data_inf);
994
                                }
995

    
996
                            // free the allocated memory 
997
                            free(recvdatabuf[i]);
998
                            recvdatabuf[i] = NULL;
999

    
1000
                            returnValue = 1;
1001
                            break;
1002

    
1003
                        }
1004
                    }
1005

    
1006
                }
1007

    
1008
            }
1009
            // printf("2 recvbuf %s \n ",recvbuf);
1010
        }
1011
        return returnValue;
1012
    }
1013
}
1014

    
1015
void setStunServer(const int port, const char *ipaddr)
1016
{
1017

    
1018
    stun_server.sin_family = AF_INET;
1019
    if (ipaddr == NULL) {
1020
        stun_server.sin_addr.s_addr = htonl(INADDR_ANY);
1021
    } else {
1022
        stun_server.sin_addr.s_addr = resolve(ipaddr);
1023
    }
1024
    stun_server.sin_port = htons(port);
1025

    
1026
}
1027

    
1028
void setRecvTimeout(struct timeval timeout_value)
1029
{
1030

    
1031
    recv_timeout = timeout_value;
1032

    
1033
}
1034

    
1035

    
1036
void
1037
create_conn_msg(char *msgbuf, int bufsize, int local_connectionID,
1038
                int external_connectionID, socketID_handle local_socketID,
1039
                socketID_handle external_socketID, int msgtype)
1040
{
1041

    
1042
    char packettype = 127;
1043
    char *msgbufptr = NULL;
1044
    int netint = 0;
1045
    // printf("connectionID %i \n",local_connectionID);
1046

    
1047
    // printf("create_conn_msg: msgtype is %d \n ",msgtype);
1048

    
1049
    switch (msgtype) {
1050
        // invite
1051
    case 0:
1052
        // write that this is a connect message
1053
        msgbuf[0] = packettype;
1054
        // write the messagetype invite
1055
        msgtype = 0;
1056
        msgbufptr = &msgbuf[1];
1057
        memcpy(msgbufptr, &msgtype, 4);
1058
        // write the connectID
1059
        netint = local_connectionID;
1060
        msgbufptr = &msgbuf[5];
1061
        memcpy(msgbufptr, &netint, 4);
1062
        // enter the pmut size
1063
        netint = bufsize;
1064
        msgbufptr = &msgbuf[9];
1065
        memcpy(msgbufptr, &netint, 4);
1066
        // write the socketID
1067
        msgbufptr = &msgbuf[13];
1068
        memcpy(msgbufptr, local_socketID, sizeof(socket_ID));
1069
        break;
1070

    
1071
        // ok
1072
    case 1:
1073
        // write that this is a connect message 
1074
        msgbuf[0] = packettype;
1075
        // write the messagetype ok 
1076
        netint = 1;
1077
        msgbufptr = &msgbuf[1];
1078
        memcpy(msgbufptr, &netint, 4);
1079
        // write the connectID_from
1080
        netint = external_connectionID;
1081
        msgbufptr = &msgbuf[5];
1082
        memcpy(msgbufptr, &netint, 4);
1083
        // write the connectID_to
1084
        netint = local_connectionID;
1085
        msgbufptr = &msgbuf[9];
1086
        memcpy(msgbufptr, &netint, 4);
1087
        // write the pmtu size
1088
        netint = bufsize;
1089
        msgbufptr = &msgbuf[13];
1090
        memcpy(msgbufptr, &netint, 4);
1091
        break;
1092

    
1093
        // ack
1094
    case 2:
1095
        // write that this is a connect message 
1096
        msgbuf[0] = packettype;
1097
        // write the messagetype ack
1098
        netint = 2;
1099
        msgbufptr = &msgbuf[1];
1100
        memcpy(msgbufptr, &netint, 4);
1101
        // write the connectID_from
1102
        netint = local_connectionID;
1103
        msgbufptr = &msgbuf[5];
1104
        memcpy(msgbufptr, &netint, 4);
1105
        // write the connectID_to 
1106
        netint = external_connectionID;
1107
        msgbufptr = &msgbuf[9];
1108
        memcpy(msgbufptr, &netint, 4);
1109
        // write the pmtu size
1110
        netint = bufsize;
1111
        msgbufptr = &msgbuf[13];
1112
        memcpy(msgbufptr, &netint, 4);
1113
        break;
1114
    }
1115

    
1116
}
1117

    
1118
void send_conn_msg(const int connectionID, char *msgbuf, int bufsize)
1119
{
1120

    
1121
    int udpSocket;
1122
    int returnValue;
1123
    socketID_handle external_socketID;
1124
    pmtu frag_size;
1125
    boolean int_connect;
1126

    
1127
    // printf("connectionID %i \n",connectionID);
1128
    // printf("bufsize %i \n",bufsize);
1129

    
1130

    
1131
    // set the socket variables
1132
    int_connect = connectbuf[connectionID]->internal_connect;
1133
    external_socketID = connectbuf[connectionID]->external_socketID;
1134

    
1135
    if (bufsize > 0) {
1136
        frag_size = bufsize;
1137
    } else {
1138

    
1139
        frag_size = max;
1140
    }
1141
    // 
1142
    udpSocket = socketfd;
1143

    
1144
    // printf("send_conn_msg: the socket fd is %i \n",udpSocket);
1145

    
1146
    // socketaddrgen udpgen = external_socketID->external_addr;
1147
    socketaddrgen udpgen;
1148

    
1149

    
1150
    if (int_connect == false) {
1151
        udpgen = external_socketID->external_addr;
1152
        // set the host order
1153
        // struct sockaddr_in udpaddr;
1154
        // udpaddr = external_socketID->external_addr.udpaddr;
1155
        // udpaddr.sin_addr.s_addr = htonl(udpaddr.sin_addr.s_addr);
1156
        // udpaddr.sin_port = htons(udpaddr.sin_port);
1157
        // udpgen.udpaddr = udpaddr;
1158
        // external_socketID->external_addr = udpgen;
1159
    } else {
1160
        udpgen = external_socketID->internal_addr;
1161
        // set the host order
1162
        // struct sockaddr_in udpaddr;
1163
        // udpaddr = external_socketID->internal_addr.udpaddr;
1164
        // udpaddr.sin_addr.s_addr = htonl(udpaddr.sin_addr.s_addr);
1165
        // udpaddr.sin_port = htons(udpaddr.sin_port);
1166
        // udpgen.udpaddr = udpaddr;
1167
        // external_socketID->internal_addr = udpgen;
1168
    }
1169

    
1170

    
1171
    struct sockaddr_in udpaddr;
1172
    udpaddr = udpgen.udpaddr;
1173

    
1174
    printf("transmissionHandler: send_conn: the port is %i  \n",
1175
           ntohs(udpaddr.sin_port));
1176
    printf("transmissionHandler: send_conn: the pmtu is %i  \n",
1177
           frag_size);
1178

    
1179
    sendPacket(udpSocket, msgbuf, frag_size, &udpgen.udpaddr, pmtu_error_cb_th);
1180
}
1181

    
1182
void
1183
recv_conn_msg(socketID_handle local_socketID, char *msgbuf, int bufsize)
1184
{
1185

    
1186
    char *msgbufptr = NULL;
1187
    int connmsgtype = 0;
1188
    int i = 0;
1189
    int pmtusize = 0;
1190
    // socketaddr *socketID_to_ptr = NULL; 
1191
    int msgtypo = 0;
1192
    char msgbufnew[bufsize];
1193
    int internal_connectionID = 0;
1194
    socketID_handle external_socketID;
1195
    int external_connectionID = 0;
1196
    int connExist = 0;
1197
    time_t now = time(NULL);
1198
    double timediff = 0.0;
1199

    
1200
    // extract the msgtype
1201
    msgbufptr = &msgbuf[1];
1202
    memcpy(&connmsgtype, msgbufptr, 4);
1203

    
1204
    // check the connection messagetype
1205
    switch (connmsgtype) {
1206

    
1207
        /*
1208
         * if invite: enter a new socket make new entry in connect array
1209
         * send an ok 
1210
         */
1211
    case 0:
1212
        // create a ptr to a socketaddr and allocate memory
1213
        // socketID_to_ptr = (socketaddr *)malloc(sizeof(socketaddr));
1214
        // copy the socketaddr from the message
1215

    
1216

    
1217
        // extract the pmtu size
1218
        msgbufptr = &msgbuf[9];
1219
        memcpy(&pmtusize, msgbufptr, 4);
1220

    
1221

    
1222
        msgbufptr = &msgbuf[13];
1223
        external_socketID = malloc(sizeof(socket_ID));
1224
        memcpy(external_socketID, msgbufptr, sizeof(socket_ID));
1225

    
1226
        /*
1227
         * debug info 
1228
         */
1229
        printf("transmissionHandler: __________________ \n ");
1230
        printf("transmissionHandler: received invite \n ");
1231

    
1232
        // ::add check if socketID is already known
1233

    
1234
        msgbufptr = &msgbuf[5];
1235
        memcpy(&external_connectionID, msgbufptr, 4);
1236

    
1237
        socketaddrgen udpgen;
1238
        udpgen = external_socketID->external_addr;
1239
        struct sockaddr_in udpaddr;
1240
        udpaddr = external_socketID->external_addr.udpaddr;
1241
        // printf("+++port is %d \n",udpaddr.sin_port);
1242

    
1243
        udpaddr.sin_addr.s_addr = htonl(udpaddr.sin_addr.s_addr);
1244
        udpaddr.sin_port = htons(udpaddr.sin_port);
1245
        udpgen.udpaddr = udpaddr;
1246
        external_socketID->external_addr = udpgen;
1247

    
1248
        /*
1249
         * check if another connection for the external connectionID exist 
1250
         * that was established within the last 2 seconds 
1251
         */
1252
        for (i = 0; i < CONNECTBUFSIZE; i++) {
1253

    
1254
            if (connectbuf[i] != NULL) {
1255

    
1256
                if (compare_socketIDs
1257
                    (connectbuf[i]->external_socketID,
1258
                     external_socketID) == 0) {
1259

    
1260
                    timediff = difftime(now, connectbuf[i]->starttime);
1261
                    if (timediff < 2) {
1262
                        connExist = 1;
1263
                    }
1264

    
1265
                }
1266
            }
1267
        }
1268

    
1269

    
1270
        if (connExist == 0) {
1271

    
1272
            // create an entry in the connecttrybuf 
1273
            for (i = 0; i < CONNECTBUFSIZE; i++) {
1274

    
1275
                if (connectbuf[i] == NULL) {
1276

    
1277
                    connectbuf[i] = (connect_data *) malloc(sizeof(connect_data));
1278
                         connectbuf[i]->connection_head = connectbuf[i]->connection_last = NULL;
1279
                    connectbuf[i]->starttime = time(NULL);
1280
                    connectbuf[i]->external_socketID = external_socketID;
1281
                    connectbuf[i]->pmtusize = pmtusize;
1282
                    connectbuf[i]->status = 1;
1283
                    connectbuf[i]->external_connectionID = external_connectionID;
1284
                    internal_connectionID = i;
1285
                    break;
1286
                }
1287

    
1288
            }
1289

    
1290
            // create and send the ok conn message 
1291
            msgtypo = 1;
1292
            // printf("internal connectionID %d \n",
1293
            // internal_connectionID);
1294
            create_conn_msg(msgbufnew, pmtusize, internal_connectionID,
1295
                            external_connectionID, NULL, NULL, msgtypo);
1296

    
1297
            send_conn_msg(internal_connectionID, msgbufnew, pmtusize);
1298

    
1299
            break;
1300

    
1301
        } else {
1302

    
1303
            break;
1304
        }
1305
        /*
1306
         * if ok: find the entry in the connectiontry array create/send an 
1307
         * ack make an entry in the connection array delete the entry in
1308
         * the connection_try array 
1309
         */
1310
    case 1:
1311
        printf("transmissionHandler: __________________ \n ");
1312
        printf("transmissionHandler: received ok \n ");
1313

    
1314
        // extract the connect_try array position 
1315
        msgbufptr = &msgbuf[9];
1316
        memcpy(&external_connectionID, msgbufptr, 4);
1317
        printf("transmissionHandler: external connectionID %i \n",
1318
               external_connectionID);
1319

    
1320
        // extract pmtu size
1321
        msgbufptr = &msgbuf[13];
1322
        memcpy(&pmtusize, msgbufptr, 4);
1323
        printf("transmissionHandler: pmtusize %i \n", pmtusize);
1324
        // extract the connecttry_ID_to
1325

    
1326
        msgbufptr = &msgbuf[5];
1327
        memcpy(&internal_connectionID, msgbufptr, 4);
1328
        printf("transmissionHandler: internal connectionID %i \n",
1329
               internal_connectionID);
1330

    
1331
        /*
1332
         * check if the connection status is not already 1 or 2 
1333
         */
1334
        if (connectbuf[internal_connectionID]->status == 0) {
1335

    
1336
            // set the external connectionID
1337
            connectbuf[internal_connectionID]->external_connectionID =
1338
                external_connectionID;
1339

    
1340
            // change status in the connection_data
1341
            connectbuf[internal_connectionID]->status = 2;
1342

    
1343
            // change pmtusize in the connection_data
1344
            connectbuf[internal_connectionID]->pmtusize = pmtusize;
1345
            connectbuf[internal_connectionID]->pmtutrysize = pmtusize;
1346

    
1347
            if (receive_Connection_cb != NULL)
1348
                (receive_Connection_cb) (internal_connectionID, NULL);
1349

    
1350

    
1351
                 while(connectbuf[internal_connectionID]->connection_head != NULL) {
1352
                        struct receive_connection_cb_list *temp;
1353
                        temp = connectbuf[internal_connectionID]->connection_head;
1354
                        (temp->connection_cb) (internal_connectionID, temp->arg);
1355
                        connectbuf[internal_connectionID]->connection_head = temp->next;
1356
                        free(temp);
1357
            }
1358
                  connectbuf[internal_connectionID]->connection_head = connectbuf[internal_connectionID]->connection_last = NULL;
1359

    
1360
            // change the status
1361
            // connectbuf[internal_connectionID]->status = 2;
1362

    
1363
            // extrackt the socketID
1364
            // internal_socketID = connectbuf[internal_connectionID]-> ;
1365

    
1366
            // send the ack
1367
            msgtypo = 2;
1368
            create_conn_msg(msgbufnew, pmtusize, internal_connectionID,
1369
                            external_connectionID, NULL, NULL, msgtypo);
1370
            send_conn_msg(internal_connectionID, msgbufnew, pmtusize);
1371
            printf
1372
                ("transmissionHandler: active connection established \n");
1373
            // connection_establisched(connectionID_this_peer);
1374

    
1375
            break;
1376

    
1377
        } else {
1378

    
1379
            break;
1380
        }
1381

    
1382
        /*
1383
         * if ack: find the entry in the connection array set the
1384
         * connection active change the pmtu size 
1385
         */
1386
    case 2:
1387
        printf("transmissionHandler: __________________ \n ");
1388
        printf("transmissionHandler: received ack \n ");
1389

    
1390
        // extract the connect_try array position 
1391
        msgbufptr = &msgbuf[9];
1392
        memcpy(&internal_connectionID, msgbufptr, 4);
1393

    
1394
        // extract pmtu size
1395
        msgbufptr = &msgbuf[13];
1396
        memcpy(&pmtusize, msgbufptr, 4);
1397

    
1398
        printf("internal connectionID: %d \n", internal_connectionID);
1399
        printf("connection status : %d \n",
1400
               connectbuf[internal_connectionID]->status);
1401

    
1402
        /*
1403
         * checks if the connection is not already established 
1404
         */
1405
        if (connectbuf[internal_connectionID]->status == 1) {
1406

    
1407
            // change status of the connection
1408
            connectbuf[internal_connectionID]->status = 2;
1409

    
1410
            // change pmtusize
1411
            connectbuf[internal_connectionID]->pmtusize = pmtusize;
1412

    
1413
            printf
1414
                ("transmissionHandler: passiv connection established \n");
1415

    
1416
            if (receive_Connection_cb != NULL)
1417
                (receive_Connection_cb) (internal_connectionID, NULL);
1418

    
1419
                 while(connectbuf[internal_connectionID]->connection_head != NULL) {
1420
                        struct receive_connection_cb_list *temp;
1421
                        temp = connectbuf[internal_connectionID]->connection_head;
1422
                        (temp->connection_cb) (internal_connectionID, temp->arg);
1423
                        connectbuf[internal_connectionID]->connection_head = temp->next;
1424
                        free(temp);
1425
            }
1426
                 connectbuf[internal_connectionID]->connection_head = connectbuf[internal_connectionID]->connection_last = NULL;
1427
            // connection_establisched(connectionID_this_peer);
1428
            // printf("going here \n ");
1429
            // main_callback(0);
1430
            break;
1431

    
1432
        } else {
1433

    
1434
            break;
1435

    
1436
        }
1437
    }
1438

    
1439
}
1440

    
1441
/*
1442
 * what to do once a packet arrived if it is a conn packet send it to
1443
 * recv_conn handler if it is a data packet send it to the recv_data
1444
 * handler 
1445
 */
1446

    
1447
// get the file descriptor directly
1448
void recv_pkg(int fd, short event, void *arg)
1449
{
1450

    
1451
    printf("transmissionHandler: recv_pkg is called \n ");
1452

    
1453
    pmtu pkgsize = max;
1454
    char msgbuf[max];
1455
    int ttl;
1456
    struct sockaddr_in recv_addr;
1457
    // int rt = 0;
1458
    int recvSize;
1459

    
1460
    recvPacket(fd, msgbuf, &recvSize, &recv_addr, pmtu_error_cb_th, &ttl);
1461

    
1462
    // check if it is not just an error message
1463
    if (ttl != -1) {
1464

    
1465
        unsigned short stun_bind_response = 0x0101;
1466
        unsigned short msgspot;
1467
        memcpy(&msgspot, msgbuf, sizeof(unsigned short));
1468
        char packettype;
1469
        StunMessage stunmsg;
1470
        packettype = msgbuf[0];
1471

    
1472
        if (msgspot == stun_bind_response) {
1473

    
1474
            printf
1475
                ("transmissionHandler: recv_pkg: parse stun message is called \n");
1476

    
1477
            recv_stun_msg(msgbuf, recvSize);
1478

    
1479
        } else if (packettype == 127) {
1480
            // send it of to the handler
1481

    
1482
            printf("transmissionHandler: received conn pkg \n ");
1483

    
1484
            recv_conn_msg(&local_socketID, msgbuf, recvSize);
1485

    
1486
        } else if (packettype < 127) {
1487

    
1488
            // need to check if this is really a data message 
1489

    
1490
            printf("transmissionHandler: received data pkg \n ");
1491

    
1492
            recv_data_msg(msgbuf, recvSize, ttl);
1493

    
1494
        }
1495
        // printf("recv_pkg is done \n ");
1496
    } else {
1497

    
1498
        printf
1499
            ("transmissionHandler: recv_pkg got only unrelated error \n ");
1500
    }
1501

    
1502

    
1503
}
1504

    
1505
void recv_stun_msg(char *msgbuf, int recvSize)
1506
{
1507

    
1508
    /*
1509
     * create empty stun message struct 
1510
     */
1511
    StunMessage resp;
1512
    memset(&resp, 0, sizeof(StunMessage));
1513
    /*
1514
     * parse the message 
1515
     */
1516
    int returnValue = 0;
1517
    returnValue = recv_stun_message(msgbuf, recvSize, &resp);
1518

    
1519
    if (returnValue == 0) {
1520
        /*
1521
         * read the reflexive Address into the local_socketID 
1522
         */
1523
        struct sockaddr_in reflexiveAddr;
1524
        reflexiveAddr.sin_family = AF_INET;
1525
        reflexiveAddr.sin_addr.s_addr = resp.mappedAddress.ipv4.addr;
1526
        reflexiveAddr.sin_port = resp.mappedAddress.ipv4.port;
1527
        socketaddrgen reflexiveAddres;
1528
        reflexiveAddres.udpaddr = reflexiveAddr;
1529
        local_socketID.external_addr = reflexiveAddres;
1530
        NAT_traversal = true;
1531

    
1532
        /*
1533
         * just debug 
1534
         */
1535
        UInt32 ip_addr = reflexiveAddr.sin_addr.s_addr;
1536
        char mapped_addr[16];
1537
        sprintf(mapped_addr, "%d.%d.%d.%d", (ip_addr >> 24) & 0xff,
1538
                (ip_addr >> 16) & 0xff, (ip_addr >> 8) & 0xff,
1539
                ip_addr & 0xff);
1540

    
1541
        printf("transmissionHandler: mapped Address %s port %i \n ",
1542
               mapped_addr, reflexiveAddr.sin_port);
1543

    
1544
    }
1545
    // callback to the upper layer indicating that the socketID is now
1546
    // ready to use
1547
    (receive_SocketID_cb) (&local_socketID, 0);
1548

    
1549
}
1550

    
1551
// process a singe recv data message
1552
void recv_data_msg(char *msgbuf, int bufsize, int ttl)
1553
{
1554

    
1555
    printf("transmissionHandler: received data message \n");
1556

    
1557
    int local_connectionID;
1558
    int seqnr;
1559
    int offset;
1560
    int size;
1561
    char *msgbufptr = NULL;
1562
    int i = 0;
1563
    boolean _bool = FALSE;
1564
    char msgtype;
1565
    /*
1566
     * The monitoring header type has a range from 0 to 3
1567
     * The numbers determine if a monitoring packet hader / monitoring data header is present
1568
     * 
1569
     *     monitoring header type | data header | pkt header
1570
     *     -------------------------------------------------
1571
     *               0            |     No      |    No
1572
     *               1            |     Yes     |    No
1573
     *               2            |     No      |    Yes
1574
     *               3            |     Yes     |    Yes
1575
     */
1576

    
1577
    char monitoringHeaderType = 0;
1578
    char monitoringDataHeader[MON_DATA_HEADER_SIZE];
1579
    int monitoring_data_header_set = 0;
1580
    int monitoring_pkt_header_set = 0;
1581

    
1582
    // extract msgtype
1583
    msgbufptr = &msgbuf[0];
1584
    memcpy(&msgtype, msgbufptr, 1);
1585
    printf("msgtype %d \n", msgtype);
1586

    
1587
    // extract connectionID
1588
    msgbufptr = &msgbuf[1];
1589
    memcpy(&local_connectionID, msgbufptr, 4);
1590
    printf("local_connectionID %d \n", local_connectionID);
1591

    
1592
    // extract seqnrg
1593
    msgbufptr = &msgbuf[5];
1594
    memcpy(&seqnr, msgbufptr, 4);
1595
    printf("seqnr %d \n", seqnr);
1596

    
1597
    // data offset
1598
    msgbufptr = &msgbuf[9];
1599
    memcpy(&offset, msgbufptr, 4);
1600
    printf("offset is %d \n", offset);
1601

    
1602
    char firstPacketArrived = 0;
1603
    if (offset == 0)
1604
                firstPacketArrived = 1;
1605

    
1606
    // size 
1607
    msgbufptr = &msgbuf[13];
1608
    memcpy(&size, msgbufptr, 4);
1609
    printf("size is %d \n", size);
1610

    
1611
    // hasMonitoringHeader
1612
    msgbufptr = &msgbuf[17];
1613
    memcpy(&monitoringHeaderType, msgbufptr, 1);
1614
    printf("monitoring header type %d \n ", monitoringHeaderType);
1615

    
1616
        /*
1617
         * make a callback to the monitoring module after a message is recv 
1618
         */
1619
        if(get_Recv_pkt_inf_cb != NULL) {
1620
                mon_pkt_inf msginfNow;
1621
                if (monitoringHeaderType == 2 || monitoringHeaderType == 3)
1622
                        msginfNow.monitoringHeader = &msgbuf[18];
1623
                else
1624
                        msginfNow.monitoringHeader = NULL;
1625
                msginfNow.remote_socketID = connectbuf[local_connectionID]->external_socketID;
1626
                msginfNow.buffer = msgbuf;
1627
                msginfNow.bufSize = bufsize;
1628
                msginfNow.msgtype = msgtype;
1629
                msginfNow.monitoringHeaderType = monitoringHeaderType;
1630
                msginfNow.ttl = ttl;
1631
                msginfNow.dataID = seqnr;
1632
                msginfNow.offset = offset;
1633
                msginfNow.datasize = size;
1634
                gettimeofday(&msginfNow.arrival_time, NULL);
1635
                (get_Recv_pkt_inf_cb) ((void *) &msginfNow);
1636
        }
1637

    
1638
        // check if a recv_data exist and enter data
1639
        for (i = 0; i < RECVDATABUFSIZE; i++) {
1640
                if (recvdatabuf[i] != NULL) {
1641
                        if (local_connectionID == recvdatabuf[i]->connectionID && seqnr == recvdatabuf[i]->seqnr) {
1642

    
1643
                                printf("connID %d\n", recvdatabuf[i]->connectionID);
1644
                                printf("seqnr %d\n", recvdatabuf[i]->seqnr);
1645

    
1646
                                if (firstPacketArrived = 1) {
1647
                                        recvdatabuf[i]->firstPacketArrived = 1;
1648
                                }
1649
                                // increment fragmentnr
1650
                                recvdatabuf[i]->recvFragments = recvdatabuf[i]->recvFragments + 1;
1651
                                int fragmentsize = connectbuf[local_connectionID]->pmtusize - MSGL_HEADER_SIZE;
1652
                                char *bufptr = NULL;
1653
                                bufptr = recvdatabuf[i]->recvbuf;
1654
                                bufptr += offset;
1655
                                // enter the data into the buffer
1656
                                int cpysize = fragmentsize;
1657

    
1658
                                // check for last fragment
1659
                                if (recvdatabuf[i]->nrFragments == recvdatabuf[i]->recvFragments) {
1660
                                        cpysize = recvdatabuf[i]->bufsize - offset;
1661
                                }
1662
                                // adapt copy size for the last fragment without
1663
                                // monitoring header
1664
                                if (monitoringHeaderType == 0 || monitoringHeaderType == 1) {
1665
                                        // adapt copy size for the last fragment with the
1666
                                        // monitoring header
1667
                                        msgbufptr = &msgbuf[18];
1668
                                        memcpy(bufptr, msgbufptr, cpysize);
1669
                                } else if (monitoringHeaderType == 2 || monitoringHeaderType == 3) {
1670
                                        int bufpos = MSGL_HEADER_SIZE + MON_PACKET_HEADER_SIZE;
1671
                                        printf("bufpos %d \n", bufpos);
1672
                                        msgbufptr = &msgbuf[bufpos];
1673
                                        // cpysize = cpysize + MON_PACKET_HEADER_SIZE;
1674
                                        printf("cpyssize %d \n", cpysize);
1675
                                        memcpy(bufptr, msgbufptr, cpysize);
1676
                                }
1677

    
1678
                                _bool = TRUE;
1679

    
1680
                                /*
1681
                                 * all fragments arrived and it are multiple fragments 
1682
                                 */
1683

    
1684
                                if (recvdatabuf[i]->nrFragments == recvdatabuf[i]->recvFragments) {
1685
                                        if (firstPacketArrived = 1) {
1686
                                        recvdatabuf[i]->firstPacketArrived = 1;
1687
                                }
1688

    
1689
                                printf("set the status of recvbuf 1  \n");
1690
                                recvdatabuf[i]->status = 1;
1691

    
1692
                                // extract the monitoring module data header
1693
                                if (monitoringHeaderType == 1 || monitoringHeaderType == 3) {
1694
                                        memcpy(monitoringDataHeader, recvdatabuf[i]->recvbuf, MON_DATA_HEADER_SIZE);
1695

    
1696
                                        // shorten the recv buffer and change the
1697
                                        // buffersize
1698
                                        recvdatabuf[i]->recvbuf += MON_DATA_HEADER_SIZE;
1699
                                        recvdatabuf[i]->bufsize -= MON_DATA_HEADER_SIZE;
1700
                                        recvdatabuf[i]->monitoringDataHeader = monitoringDataHeader;
1701
                                }
1702

    
1703
                                if (recv_data_callback) {
1704

    
1705
                                        // get the msgtype
1706
                                        char msgtype = recvdatabuf[i]->msgtype;
1707

    
1708
                                        // get the right callback
1709
                                        receive_data_cb receive_data_callback = recvcbbuf[msgtype];
1710
                                        bufptr = recvdatabuf[i]->recvbuf;
1711
                                        size = recvdatabuf[i]->bufsize;
1712
                                        // call the callback
1713
                                        // printf("msgbuf %s \n",msgbuf);
1714

    
1715
                                        // nr missing fragments calculate
1716

    
1717
                                        recv_params rParams;
1718

    
1719
                                        double nrMissFrags = (double) recvdatabuf[i]->nrFragments / (double) recvdatabuf[i]->recvFragments;
1720
                                        int nrMissingFragments = (int) ceil(nrMissFrags);
1721

    
1722
                                        rParams.nrMissingFragments = nrMissingFragments;
1723
                                        rParams.nrFragments = recvdatabuf[i]->nrFragments;
1724
                                        rParams.msgtype = recvdatabuf[i]->msgtype;
1725
                                        rParams.connectionID = recvdatabuf[i]->connectionID;
1726
                                        rParams.remote_socketID = connectbuf[recvdatabuf[i]->connectionID]->external_socketID;
1727
                                        /*
1728
                                        * if(monitoringHeaderType == 1 ||
1729
                                        * monitoringHeaderType == 3){
1730
                                        * rParams->monitoring_header_data =
1731
                                        * monitoringDataHeader; }else{
1732
                                        * rParams->monitoring_header_data = NULL; } 
1733
                                        */
1734

    
1735
                                        rParams.firstPacketArrived = recvdatabuf[i]->firstPacketArrived;
1736

    
1737
                                        if(get_Recv_data_inf_cb != NULL) {
1738
                                                mon_data_inf recv_data_inf;
1739

    
1740
                                                recv_data_inf.remote_socketID = connectbuf[recvdatabuf[i]->connectionID]->external_socketID;
1741
                                                recv_data_inf.buffer = recvdatabuf[i]->recvbuf;
1742
                                                recv_data_inf.bufSize = recvdatabuf[i]->bufsize;
1743
                                                recv_data_inf.msgtype = recvdatabuf[i]->msgtype;
1744
                                                recv_data_inf.monitoringHeaderType = recvdatabuf[i]->monitoringHeaderType;
1745
                                                recv_data_inf.monitoringDataHeader = recvdatabuf[i]->monitoringDataHeader;
1746
                                                gettimeofday(&recv_data_inf.arrival_time, NULL);
1747
                                                recv_data_inf.firstPacketArrived = recvdatabuf[i]->firstPacketArrived;
1748
                                                recv_data_inf.nrMissingFragments = nrMissingFragments;
1749
                                                recv_data_inf.nrFragments = recvdatabuf[i]->nrFragments;
1750
                                                recv_data_inf.priority = false;
1751
                                                recv_data_inf.padding = false;
1752
                                                recv_data_inf.confirmation = false;
1753
                                                recv_data_inf.reliable = false;
1754

    
1755
                                                // send data recv callback to monitoring module
1756

    
1757
                                                (get_Recv_data_inf_cb) ((void *) &recv_data_inf);
1758
                                        }
1759

    
1760
                                        (receive_data_callback) (bufptr, size, msgtype, (void *) &rParams);
1761

    
1762
                                        free(recvdatabuf[i]);
1763
                                        recvdatabuf[i] = NULL;
1764
                                }
1765
                        }
1766
                }
1767
                }
1768
        }
1769

    
1770

    
1771
   // if the dataID and connectionId dont exist: create a new recv object
1772
        if (_bool == FALSE) {
1773
                for (i = 0; i < RECVDATABUFSIZE; i++) {
1774
                        if (recvdatabuf[i] == NULL) {
1775
                                recvdatabuf[i] = (recvdata *) malloc(sizeof(recvdata));
1776
                                recvdatabuf[i]->connectionID = local_connectionID;
1777
                                recvdatabuf[i]->seqnr = seqnr;
1778
                                recvdatabuf[i]->bufsize = size;
1779
                                recvdatabuf[i]->recvbuf = (char *) malloc(size);
1780
                                /*
1781
                                 * read the set timeout data and set it 
1782
                                 */
1783
                                recvdatabuf[i]->timeout_value.tv_sec = recv_timeout.tv_sec;
1784
                                recvdatabuf[i]->timeout_value.tv_usec = recv_timeout.tv_usec;
1785
                                recvdatabuf[i]->recvID = i;
1786
                                recvdatabuf[i]->starttime = time(NULL);
1787
                                recvdatabuf[i]->recvFragments = 1;
1788
                                recvdatabuf[i]->msgtype = msgtype;
1789
                                recvdatabuf[i]->monitoringHeaderType =        monitoringHeaderType;
1790
                                recvdatabuf[i]->firstPacketArrived = firstPacketArrived;
1791

    
1792
                                // fill the buffer with zeros
1793
                                memset(recvdatabuf[i]->recvbuf, '0', size);
1794

    
1795
                                char *bufptr = NULL;
1796
                                bufptr = recvdatabuf[i]->recvbuf;
1797
                                bufptr += offset;
1798

    
1799
                                // determine the fragmentsize
1800
                                // TODO correct this: causes segmentation faults if data is send to a not opened connection
1801
                                int fragmentsize = connectbuf[local_connectionID]->pmtusize - MSGL_HEADER_SIZE;
1802

    
1803
                                if (monitoringHeaderType == 0 || monitoringHeaderType == 1) {
1804
                                // no monitoring module header present
1805
                                        msgbufptr = &msgbuf[18];
1806
                                } else if (monitoringHeaderType == 2 || monitoringHeaderType == 3) {
1807
                                        fragmentsize = fragmentsize - MON_PACKET_HEADER_SIZE;
1808
                                        int bufpos = MON_PACKET_HEADER_SIZE + MSGL_HEADER_SIZE;
1809
                                        msgbufptr = &msgbuf[bufpos];
1810
                                        // printf("buffer %s \n ",bufptr);
1811
                                }
1812

    
1813
                                int cpysize;
1814
                                cpysize = (fragmentsize < size) ?  fragmentsize : size;
1815
                                memcpy(bufptr, msgbufptr, cpysize);
1816

    
1817

    
1818
                                double nrFrags = (double) size / (double) fragmentsize;
1819
                                int nrFragments = (int) ceil(nrFrags);
1820
                                recvdatabuf[i]->nrFragments = nrFragments;
1821

    
1822
                                /*
1823
                                * if there is only one fragment the recv is finished 
1824
                                */
1825
                                if (nrFragments == 1) {
1826
                                        recvdatabuf[i]->status = 1;
1827

    
1828
                                        // get the msgtype 
1829
                                        char msgtype = recvdatabuf[i]->msgtype;
1830

    
1831
                                        // get the right callback
1832
                                        receive_data_cb receive_data_callback = recvcbbuf[msgtype];
1833
                                        // printf("msgbuf %s \n",bufptr);
1834

    
1835
                                        // call the callback
1836
                                        recv_params rParams;
1837

    
1838
                                        double nrMissFrags =        (double) recvdatabuf[i]->nrFragments / (double) recvdatabuf[i]->recvFragments;
1839
                                        int nrMissingFragments = (int) ceil(nrMissFrags);
1840

    
1841
                                        if (monitoringHeaderType == 1 || monitoringHeaderType == 3) {
1842
                                                memcpy(monitoringDataHeader, recvdatabuf[i]->recvbuf, MON_DATA_HEADER_SIZE);
1843
                                                // shorten the recv buffer and change the
1844
                                                // buffersize 
1845
                                                recvdatabuf[i]->recvbuf += MON_DATA_HEADER_SIZE;
1846
                                                recvdatabuf[i]->bufsize -= MON_DATA_HEADER_SIZE;
1847
                                                // set this in the return parameters
1848
                                                // rParams->monitoring_header_data =
1849
                                                // monitoringDataHeader;
1850

    
1851
                                                recvdatabuf[i]->monitoringDataHeader = monitoringDataHeader;
1852
                                        } else {
1853
                                                // rParams->monitoring_header_data = NULL;
1854
                                        }
1855

    
1856
                                        rParams.nrMissingFragments = nrMissingFragments;
1857
                                        rParams.nrFragments = recvdatabuf[i]->nrFragments;
1858
                                        rParams.msgtype = recvdatabuf[i]->msgtype;
1859
                                        rParams.connectionID = recvdatabuf[i]->connectionID;
1860
                                        rParams.firstPacketArrived = 1;
1861
                                        rParams.remote_socketID = connectbuf[recvdatabuf[i]->connectionID]->external_socketID;
1862

    
1863
                                        // calback to the monitoring layer 
1864
                                        if(get_Recv_data_inf_cb != NULL) {
1865
                                                mon_data_inf recv_data_inf_;
1866

    
1867
                                                recv_data_inf_.remote_socketID = connectbuf[recvdatabuf[i]->connectionID]->external_socketID;        
1868
                                                recv_data_inf_.buffer = recvdatabuf[i]->recvbuf;
1869
                                                recv_data_inf_.bufSize = recvdatabuf[i]->bufsize;
1870
                                                recv_data_inf_.msgtype = recvdatabuf[i]->msgtype;
1871
                                                recv_data_inf_.monitoringHeaderType = recvdatabuf[i]->monitoringHeaderType;
1872
                                                recv_data_inf_.monitoringDataHeader = recvdatabuf[i]->monitoringDataHeader;
1873
                                                gettimeofday(&recv_data_inf_.arrival_time, NULL);
1874
                                                recv_data_inf_.firstPacketArrived = recvdatabuf[i]->firstPacketArrived;
1875
                                                recv_data_inf_.nrMissingFragments = nrMissingFragments;
1876
                                                recv_data_inf_.nrFragments = recvdatabuf[i]->nrFragments;
1877
                                                recv_data_inf_.priority = false;
1878
                                                recv_data_inf_.padding = false;
1879
                                                recv_data_inf_.confirmation = false;
1880
                                                recv_data_inf_.reliable = false;
1881

    
1882
                                                (get_Recv_data_inf_cb) ((void *) &recv_data_inf_);
1883
                                        }
1884

    
1885

    
1886
                                        if (receive_data_callback) {
1887
                                                (receive_data_callback) (bufptr, size, msgtype, (void *) &rParams);
1888
                                                // fill the recv_cb
1889
                                                free(recvdatabuf[i]);
1890
                                                recvdatabuf[i] = NULL;
1891
                                        }
1892
                                }
1893
                                // more then one fragment
1894
                                else {
1895

    
1896
                                        recvdatabuf[i]->status = 0;
1897

    
1898
                                        if (recv_data_callback) {
1899
                                                struct timeval timeout_value_print = { 4, 0 };
1900
                                                struct event *ev;
1901
                                                ev = evtimer_new(base, recv_timeout_cb, (void *) &recvdatabuf[i]);
1902
                                                // recvdatabuf[i]->timeout = ev;
1903
                                                event_add(ev, &recvdatabuf[i]->timeout_value);
1904
                                        }
1905
                                }
1906
                                break;
1907
                        }
1908
                        //break; missplaced ??
1909
                }
1910
        }
1911
    // printf("still here 11\n");
1912
}
1913

    
1914
void recv_timeout_cb(int fd, short event, void *arg)
1915
{
1916

    
1917
    // int recvID;
1918
    // memcpy(&recvID,arg,4);
1919
    printf("transmissionHandler: recv_timeout_cb is called \n ");
1920

    
1921
    if (arg != NULL) {
1922

    
1923
        recvdata *recvdataptr = (recvdata *) arg;
1924

    
1925
        if (recvdataptr->recvbuf != NULL) {
1926

    
1927
            recvdataptr->status = 1;
1928
            char monitoringHeaderType = recvdataptr->monitoringHeaderType;
1929
            char monitoringDataHeader[MON_DATA_HEADER_SIZE];
1930
            // check for the chunk header
1931

    
1932

    
1933
            if (monitoringHeaderType == 1 || monitoringHeaderType == 3) {
1934

    
1935
                memcpy(monitoringDataHeader, recvdataptr->recvbuf,
1936
                       MON_DATA_HEADER_SIZE);
1937

    
1938
                // shorten the recv buffer and change the buffersize 
1939

    
1940
                recvdataptr->recvbuf += MON_DATA_HEADER_SIZE;
1941
                recvdataptr->bufsize -= MON_DATA_HEADER_SIZE;
1942

    
1943
                recvdataptr->monitoringDataHeader = monitoringDataHeader;
1944
            }
1945
            // callback to the monitoring module
1946

    
1947
            if (recv_data_callback) {
1948

    
1949
                // get the msgtype 
1950
                char msgtype = recvdataptr->msgtype;
1951

    
1952
                // get the right callback
1953
                receive_data_cb receive_data_callback = recvcbbuf[msgtype];
1954

    
1955
                recv_params rParams;
1956
                double nrMissFrags = (double) recvdataptr->nrFragments / (double) recvdataptr->recvFragments; 
1957
                int nrMissingFragments = (int) ceil(nrMissFrags);
1958

    
1959
                rParams.nrMissingFragments = nrMissingFragments;
1960
                rParams.nrFragments = recvdataptr->nrFragments;
1961
                rParams.msgtype = recvdataptr->msgtype;
1962
                rParams.connectionID = recvdataptr->connectionID;
1963
                rParams.firstPacketArrived = recvdataptr->firstPacketArrived;
1964
                rParams.remote_socketID = connectbuf[recvdataptr->connectionID]->external_socketID;
1965

    
1966
                if (monitoringHeaderType == 1 || monitoringHeaderType == 3) {
1967

    
1968
                    // rParams->monitoring_header_data =
1969
                    // monitoringDataHeader;
1970

    
1971
                } else {
1972

    
1973
                    // rParams->monitoring_header_data = NULL;
1974

    
1975
                }
1976

    
1977

    
1978
                // call the callback 
1979
                (receive_data_callback) (recvdataptr->recvbuf, recvdataptr->bufsize, msgtype, (void *) &rParams);
1980

    
1981
                free(recvdataptr);
1982
                recvdataptr = NULL;
1983
            }
1984

    
1985

    
1986
        }
1987
    }
1988
}
1989

    
1990
void pmtu_timeout_cb(int fd, short event, void *arg)
1991
{
1992

    
1993
    printf("transmissionHandler: pmtu timeout called \n");
1994

    
1995
    int connectionID;
1996
    int msgtype;
1997
    pmtu pmtusize;
1998
    pmtu new_pmtusize;
1999
    char msgbufx[1500];
2000

    
2001
    connect_data *my_connect_data = (connect_data *) arg;
2002
    connectionID = my_connect_data->connectionID;
2003

    
2004

    
2005
    // retreive the connectionID
2006
    // memcpy(&connectionID,arg,4);
2007
    // printf("connId %d \n",connectionID);
2008
    // &connectionID = (int *)arg;
2009

    
2010
    // int *ptr = NULL;
2011
    // ptr = (int *)arg;
2012

    
2013

    
2014
    // get status and pmtu size
2015
    msgtype = connectbuf[connectionID]->status;
2016
    pmtusize = connectbuf[connectionID]->pmtutrysize;
2017

    
2018
    // printf("pmtusize: %i \n ",pmtusize);
2019

    
2020
    // decrement the pmtu size
2021
    new_pmtusize = pmtu_decrement(pmtusize);
2022

    
2023
    // printf("new_pmtusize: %i \n ",new_pmtusize);
2024

    
2025
    if (new_pmtusize == error) {
2026

    
2027
        if (connectbuf[connectionID]->internal_connect == true) {
2028

    
2029
            connectbuf[connectionID]->internal_connect = false;
2030

    
2031
            pmtu full = max;
2032

    
2033
            connectbuf[connectionID]->pmtutrysize = full;
2034
            connectbuf[connectionID]->pmtusize = full;
2035
            new_pmtusize = max;
2036
            // printf(" set pmtu size %i
2037
            // \n",connectbuf[connectionID]->pmtutrysize);
2038

    
2039
            // printf("--> connectionID: %i \n ",connectionID);
2040

    
2041
            int connID = connectionID;
2042
            create_conn_msg(msgbufx, 1500, connID, 0, &local_socketID,
2043
                            NULL, msgtype);
2044

    
2045
            connID = connectionID;
2046

    
2047
            send_conn_msg(connectionID, msgbufx, 1500);
2048

    
2049
            /*
2050
             * libevent2 
2051
             */
2052
            struct event *ev1;
2053
            ev1 =
2054
                evtimer_new(base, pmtu_timeout_cb,
2055
                            (void *) my_connect_data);
2056
            // connectbuf[connectionID]->timeout = ev;
2057
            // event_add(ev,&connectbuf[connectionID]->timeout_value);
2058
            evtimer_add(ev1, &connectbuf[connectionID]->timeout_value);
2059

    
2060

    
2061
            msgtype = 2;
2062

    
2063
        } else {
2064

    
2065
            // printf("still alive \n");
2066

    
2067
            fprintf(stderr,
2068
                    "transmissionHandler: Could not create connection with connectionID %i !\n",
2069
                    connectionID);
2070

    
2071
            (failed_Connection_cb) (connectionID, NULL);
2072
            // set the message type to a non existent message
2073
            msgtype = 2;
2074
            // delete the connection entry
2075
            free(connectbuf[connectionID]);
2076
            // envoke the callback for connection establishment
2077
        }
2078

    
2079
    }
2080

    
2081
    connectbuf[connectionID]->pmtutrysize = new_pmtusize;
2082

    
2083
    // set the buffer for the message
2084
    char msgbuf[new_pmtusize];
2085
    // struct event *ev;
2086

    
2087
    switch (msgtype) {
2088

    
2089
    case 0:
2090

    
2091
        // create and send a connection message
2092
        create_conn_msg(msgbuf, new_pmtusize, connectionID, 0,
2093
                        &local_socketID, NULL, msgtype);
2094

    
2095
        send_conn_msg(connectionID, msgbuf, new_pmtusize);
2096

    
2097
        // set a timeout event for the pmtu discovery 
2098
        // timeout_set(connectbuf[connectionID]->timeout,pmtu_timeout_cb,(void 
2099
        // *)&connectionID);
2100

    
2101
        // timeout_add(connectbuf[connectionID]->timeout,&connectbuf[connectionID]->timeout_value);
2102

    
2103
        printf("transmissionHandler: connId %d \n", connectionID);
2104

    
2105

    
2106
        /*
2107
         * libevent2 
2108
         */
2109
        struct event *ev1;
2110
        ev1 = evtimer_new(base, pmtu_timeout_cb, (void *) my_connect_data);
2111
        // connectbuf[connectionID]->timeout = ev;
2112
        // event_add(ev,&connectbuf[connectionID]->timeout_value);
2113
        evtimer_add(ev1, &connectbuf[connectionID]->timeout_value);
2114

    
2115
        break;
2116

    
2117
    case 1:
2118

    
2119
        // create and send a connection message
2120
        create_conn_msg(msgbuf, new_pmtusize,
2121
                        connectbuf[connectionID]->connectionID,
2122
                        connectbuf[connectionID]->external_connectionID,
2123
                        NULL, NULL, msgtype);
2124

    
2125
        send_conn_msg(connectionID, msgbuf, new_pmtusize);
2126

    
2127
        // set a timeout event for the pmtu discovery 
2128
        // timeout_set(connectbuf[connectionID]->timeout,pmtu_timeout_cb,(void 
2129
        // *)&connectionID);
2130
        // timeout_add(connectbuf[connectionID]->timeout,&connectbuf[connectionID]->timeout_value);
2131

    
2132
        /*
2133
         * libevent2 
2134
         */
2135
        struct event *ev2;
2136
        ev2 = evtimer_new(base, pmtu_timeout_cb, (void *) my_connect_data);
2137
        // connectbuf[connectionID]->timeout = ev;
2138
        event_add(ev2, &connectbuf[connectionID]->timeout_value);
2139

    
2140
        break;
2141

    
2142
    }
2143

    
2144
}
2145

    
2146
/*
2147
 * decrements the mtu size
2148
 */
2149
pmtu pmtu_decrement(pmtu pmtusize)
2150
{
2151

    
2152
    pmtu pmtu_return_size;
2153

    
2154
    if (pmtusize == max) {
2155

    
2156
        pmtu_return_size = dsl;
2157

    
2158
    } else if (pmtusize == dsl) {
2159

    
2160
        // printf("set pmtu dsl \n");
2161
        pmtu_return_size = dslmedium;
2162

    
2163
    } else if (pmtusize == dslmedium) {
2164

    
2165
        pmtu_return_size = dslslim;
2166

    
2167
    } else if (pmtusize == dslslim) {
2168

    
2169
        pmtu_return_size = belowdsl;
2170

    
2171
    } else if (pmtusize == belowdsl) {
2172

    
2173
        pmtu_return_size = min;
2174

    
2175
    } else {
2176
        printf("transmissionHandler: only unrealted error \n ");
2177
        pmtu_return_size = error;
2178

    
2179
    }
2180

    
2181
    return pmtu_return_size;
2182

    
2183
}
2184

    
2185
void pmtu_error_cb_th(char *msg, int msglen)
2186
{
2187

    
2188
    printf("pmtu error callback \n ");
2189

    
2190
    printf("+pmtu size %d \n", msglen);
2191

    
2192
    char *msgbufptr = NULL;
2193
    int msgtype;
2194
    int connectionID;
2195
    pmtu pmtusize;
2196
    pmtu new_pmtusize;
2197
    int dead = 0;
2198

    
2199
    // check the packettype
2200
    msgbufptr = &msg[0];
2201

    
2202
    // check the msgtype
2203
    msgbufptr = &msg[1];
2204
    memcpy(&msgtype, msgbufptr, 4);
2205

    
2206
    if (msgtype == 0) {
2207

    
2208
        // get the connectionID
2209
        msgbufptr = &msg[5];
2210
        memcpy(&connectionID, msgbufptr, 4);
2211

    
2212
        int msgtype_c = connectbuf[connectionID]->status;
2213
        pmtusize = connectbuf[connectionID]->pmtutrysize;
2214

    
2215
        if (msgtype_c != msgtype) {
2216
            dead = 1;
2217
        }
2218

    
2219

    
2220
    } else if (msgtype == 1) {
2221

    
2222
        // read the connectionID
2223
        msgbufptr = &msg[9];
2224
        memcpy(&connectionID, msgbufptr, 4);
2225

    
2226
        int msgtype_c = connectbuf[connectionID]->status;
2227
        pmtusize = connectbuf[connectionID]->pmtutrysize;
2228

    
2229
        if (msgtype_c != msgtype) {
2230
            dead = 1;
2231
        }
2232

    
2233
    }
2234
    // decrement the pmtu size 
2235
    new_pmtusize = pmtu_decrement(pmtusize);
2236

    
2237
    connectbuf[connectionID]->pmtutrysize = new_pmtusize;
2238

    
2239
    if (new_pmtusize == error) {
2240

    
2241

    
2242
        fprintf(stderr,
2243
                "transmissionHandler:  Could not create connection with connectionID %i !\n",
2244
                connectionID);
2245

    
2246
        (failed_Connection_cb) (connectionID, NULL);
2247
        // set the message type to a non existent message 
2248
        msgtype = 2;
2249
        // delete the connection entry 
2250
        free(connectbuf[connectionID]);
2251

    
2252
    }
2253

    
2254
    if (msgtype == 0 && dead != 1) {
2255

    
2256
        // stop the timeout event
2257
        // timeout_del(connectbuf[connectionID]->timeout);
2258
        /*
2259
         * libevent2 
2260
         */
2261

    
2262
        // event_del(connectbuf[connectionID]->timeout);
2263

    
2264
        // set the buffer for the message
2265
        char msgbuf[new_pmtusize];
2266

    
2267
        // create and send a connection message
2268
        create_conn_msg(msgbuf, new_pmtusize, connectionID, 0,
2269
                        &local_socketID, NULL, 0);
2270

    
2271
        send_conn_msg(connectionID, msgbuf, new_pmtusize);
2272

    
2273
        // set a timeout event for the pmtu discovery 
2274
        // timeout_set(connectbuf[connectionID]->timeout,pmtu_timeout_cb,(void 
2275
        // *)&connectionID);
2276

    
2277
        // timeout_add(connectbuf[connectionID]->timeout,&connectbuf[connectionID]->timeout_value);
2278

    
2279
        /*
2280
         * libevent2 
2281
         */
2282

    
2283
        struct event *ev;
2284
        ev = evtimer_new(base, pmtu_timeout_cb,
2285
                         (void *) connectbuf[connectionID]);
2286

    
2287
        // connectbuf[connectionID]->timeout = ev;
2288

    
2289
        event_add(ev, &connectbuf[connectionID]->timeout_value);
2290

    
2291
    } else if (msgtype == 1 && dead != 1) {
2292

    
2293
        // stop the timeout event
2294
        // timeout_del(connectbuf[connectionID]->timeout);
2295

    
2296
        /*
2297
         * libevent2 
2298
         */
2299
        // printf("still here 11 \n");
2300
        // printf("ev %d \n",connectbuf[connectionID]->timeout);
2301
        // event_del(connectbuf[connectionID]->timeout );
2302
        // evtimer_del(connectbuf[connectionID]->timeout );
2303

    
2304
        char msgbufn[new_pmtusize];
2305

    
2306
        // create and send a connection message
2307
        create_conn_msg(msgbufn, new_pmtusize,
2308
                        connectbuf[connectionID]->connectionID,
2309
                        connectbuf[connectionID]->external_connectionID,
2310
                        NULL, NULL, 1);
2311

    
2312
        send_conn_msg(connectionID, msgbufn, new_pmtusize);
2313

    
2314
        // set a timeout event for the pmtu discovery 
2315
        // timeout_set(connectbuf[connectionID]->timeout,pmtu_timeout_cb,(void 
2316
        // *)&connectionID);
2317
        // timeout_add(connectbuf[connectionID]->timeout,&connectbuf[connectionID]->timeout_value);
2318

    
2319
        /*
2320
         * libevent2 
2321
         */
2322
        // struct event *ev;
2323
        // ev = evtimer_new(base,pmtu_timeout_cb, (void
2324
        // *)connectbuf[connectionID]);
2325
        // connectbuf[connectionID]->timeout = ev;
2326
        // event_add(ev,&connectbuf[connectionID]->timeout_value);
2327

    
2328
    }
2329

    
2330

    
2331
}
2332

    
2333
/*
2334
 * compare the external IP address of two socketIDs 
2335
 */
2336
int
2337
compare_external_address_socketIDs(socketID_handle sock1,
2338
                                   socketID_handle sock2)
2339
{
2340

    
2341
    int resultValue = 0;
2342
    socketaddrgen udpgen1;
2343
    socketaddrgen udpgen2;
2344
    struct sockaddr_in udpaddr1;
2345
    struct sockaddr_in udpaddr2;
2346

    
2347
    /*
2348
     * compare internal addr 
2349
     */
2350
    udpgen1 = sock1->internal_addr;
2351
    udpgen2 = sock2->internal_addr;
2352

    
2353
    udpaddr1 = udpgen1.udpaddr;
2354
    udpaddr2 = udpgen2.udpaddr;
2355

    
2356
    if (udpaddr1.sin_addr.s_addr != udpaddr2.sin_addr.s_addr) {
2357

    
2358
        resultValue = 1;
2359

    
2360
    }
2361

    
2362
    return resultValue;
2363

    
2364
}
2365

    
2366

    
2367
/*
2368
 * hash code of a socketID
2369
 * TODO might think of a better way
2370
 */
2371
int hash_socketID(socketID_handle sock)
2372
{
2373
    return sock->internal_addr.udpaddr.sin_port +
2374
                          sock->external_addr.udpaddr.sin_port;
2375
}
2376

    
2377
/*
2378
 * compares 2 socketIDs: returns 0 if they are equl otherwise 1 
2379
 */
2380
int compare_socketIDs(socketID_handle sock1, socketID_handle sock2)
2381
{
2382
        /*
2383
        * compare internal addr 
2384
        */
2385
        if (sock1->internal_addr.udpaddr.sin_addr.s_addr != 
2386
            sock2->internal_addr.udpaddr.sin_addr.s_addr)
2387
                        return 1;
2388

    
2389
        if (sock1->internal_addr.udpaddr.sin_port !=
2390
                 sock2->internal_addr.udpaddr.sin_port)
2391
                        return 1;
2392

    
2393
        /*
2394
        * compare external addr 
2395
        */
2396
        if (sock1->external_addr.udpaddr.sin_addr.s_addr != 
2397
            sock2->external_addr.udpaddr.sin_addr.s_addr)
2398
                        return 1;
2399

    
2400
        if (sock1->external_addr.udpaddr.sin_port !=
2401
                 sock2->external_addr.udpaddr.sin_port)
2402
                        return 1;
2403

    
2404
        return 0;
2405
}
2406

    
2407
/*
2408
 * the timeout of the NAT traversal 
2409
 */
2410
void nat_traversal_timeout(int fd, short event, void *arg)
2411
{
2412

    
2413
    // socketID_handle socketID = (void *)arg;
2414

    
2415
    if (NAT_traversal == false) {
2416

    
2417
        printf("transmissionHandler: NAT traversal resend \n ");
2418
        send_stun_request(socketfd, &stun_server);
2419

    
2420
        /*
2421
         * enter a NAT traversal timeout that takes care of retransmission 
2422
         */
2423
        struct event *ev1;
2424
        struct timeval timeout_value_NAT_traversal = { 1, 0 };
2425
        ev1 = evtimer_new(base, nat_traversal_timeout, NULL);
2426
        event_add(ev1, &timeout_value_NAT_traversal);
2427
        // callback to the upper layer indicating that NAT traversal
2428
        // failed
2429
        (receive_SocketID_cb) (&local_socketID, 2);
2430

    
2431
    }
2432

    
2433
}
2434

    
2435
int get_standard_ttl(socketID_handle socketID, uint8_t *ttl)
2436
{
2437

    
2438
    evutil_socket_t socket = socketfd;
2439
    int returnValue = 0;
2440

    
2441
    returnValue = getTTL(socket, ttl);
2442

    
2443
    return returnValue;
2444
}
2445

    
2446
socketID_handle get_local_socketID(int *errorstatus)
2447
{
2448

    
2449
    if (NAT_traversal == false) {
2450

    
2451
        *errorstatus = 2;
2452

    
2453
    } else {
2454

    
2455
        *errorstatus = 0;
2456

    
2457
    }
2458

    
2459
    return &local_socketID;
2460

    
2461
}
2462

    
2463

    
2464
int get_external_IP(char *external_addr)
2465
{
2466

    
2467
    socketaddrgen udpgen;
2468
    struct sockaddr_in udpaddr;
2469

    
2470
    udpgen = local_socketID.external_addr;
2471
    udpaddr = udpgen.udpaddr;
2472

    
2473
    inet_ntop(AF_INET, &(udpaddr.sin_addr), external_addr,
2474
              INET_ADDRSTRLEN);
2475

    
2476
    if (external_addr == NULL) {
2477

    
2478
        return -1;
2479

    
2480
    } else {
2481

    
2482
        return 0;
2483

    
2484
    }
2485

    
2486
}
2487

    
2488
int print_socketID(socketID_handle socketID)
2489
{
2490

    
2491
    socketaddrgen udpgen;
2492
    struct sockaddr_in udpaddr;
2493
    char external_addr[INET_ADDRSTRLEN];
2494
    udpgen = socketID->external_addr;
2495
    udpaddr = udpgen.udpaddr;
2496
    // save external port
2497
    int external_port = udpaddr.sin_port;
2498
    // convert external IP address from binary to string
2499
    inet_ntop(AF_INET, &(udpaddr.sin_addr), external_addr,
2500
              INET_ADDRSTRLEN);
2501

    
2502
    char internal_addr[INET_ADDRSTRLEN];
2503
    udpgen = socketID->internal_addr;
2504
    udpaddr = udpgen.udpaddr;
2505
    // save external port
2506
    int internal_port = udpaddr.sin_port;
2507
    // convert internal IP address from binary to string
2508
    inet_ntop(AF_INET, &(udpaddr.sin_addr), internal_addr,
2509
              INET_ADDRSTRLEN);
2510

    
2511
    if (external_addr == NULL || internal_addr == NULL)
2512
                return -1;
2513

    
2514
        printf("Ext %s:%d Int %s:%d\n",external_addr,external_port,internal_addr,internal_port);
2515
}
2516

    
2517
int socketID_to_String(socketID_handle sock, char *sock_string)
2518
{
2519
        char internal_addr[INET_ADDRSTRLEN];
2520
        char external_addr[INET_ADDRSTRLEN];
2521
   inet_ntop(AF_INET, &(sock->internal_addr.udpaddr.sin_addr.s_addr), internal_addr, INET_ADDRSTRLEN);
2522
        inet_ntop(AF_INET, &(sock->external_addr.udpaddr.sin_addr.s_addr), external_addr, INET_ADDRSTRLEN);
2523
        
2524
        sprintf(sock_string,"%s:%d %s:%d", internal_addr, sock->internal_addr.udpaddr.sin_port,
2525
                external_addr,        sock->external_addr.udpaddr.sin_port);
2526
        return 0;
2527
}
2528

    
2529
int string_to_socketID(char* socketID_string, socketID_handle sock)
2530
{
2531
        //@TODO add checks against malformed string
2532
        char external_addr[INET_ADDRSTRLEN];
2533
        int external_port;
2534
        char internal_addr[INET_ADDRSTRLEN];
2535
        int internal_port;
2536

    
2537
        char *pch;
2538

    
2539
        //replace ':' with a blank
2540
        pch=strchr(socketID_string,':');
2541
        while (pch!=NULL){
2542
                                *pch = ' ';
2543
                pch=strchr(pch+1,':');
2544
        }
2545

    
2546
        sscanf(socketID_string,"%s %d %s %d", internal_addr, &internal_port,
2547
                external_addr, &external_port);
2548

    
2549
        sock->internal_addr.udpaddr.sin_addr.s_addr = inet_addr(internal_addr);
2550
        sock->internal_addr.udpaddr.sin_port = internal_port;
2551

    
2552
        sock->external_addr.udpaddr.sin_addr.s_addr = inet_addr(external_addr);
2553
        sock->external_addr.udpaddr.sin_port = external_port;
2554
        return 0;
2555
}
2556

    
2557

    
2558
int get_connection_status(int connectionID)
2559
{
2560

    
2561
    // get the connection status
2562
    int stat = 0;
2563
    stat = connectbuf[connectionID]->status;
2564
    // translate the status
2565
    int returnvalue = 0;
2566

    
2567
    if (stat != 2) {
2568

    
2569
        returnvalue = -1;
2570

    
2571
    }
2572

    
2573
    return returnvalue;
2574

    
2575
}
2576

    
2577

    
2578
int connection_exist(socketID_handle socketID)
2579
{
2580

    
2581

    
2582
    int i = 0;
2583

    
2584
    /*
2585
     * check if another connection for the external connectionID exist
2586
     * that was established \ within the last 2 seconds 
2587
     */
2588
    for (i = 0; i < CONNECTBUFSIZE; i++) {
2589

    
2590
        if (connectbuf[i] != NULL) {
2591

    
2592
            if (compare_socketIDs
2593
                (connectbuf[i]->external_socketID, socketID)
2594
                == 0) {
2595

    
2596
                return i;
2597

    
2598
            }
2599

    
2600
        }
2601
    }
2602

    
2603
    return -1;
2604
}
2605

    
2606
unsigned long resolve(const char *ipaddr)
2607
{
2608
    struct hostent *h = gethostbyname(ipaddr);
2609
    if (!h) {
2610
        fprintf(stderr, "Unable to resolve hostname %s\n", ipaddr);
2611
        exit(-1);
2612
    }
2613
    unsigned long *addr = (unsigned long *) (h->h_addr);
2614
    return *addr;
2615
}