Statistics
| Branch: | Revision:

ml / transmissionHandler.c @ 4f1a41e6

History | View | Annotate | Download (67.6 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;
125
set_monitoring_header_pkt_cb set_Monitoring_header_pkt_cb;
126
get_recv_data_inf_cb get_Recv_data_inf_cb;
127
get_send_data_inf_cb get_Send_data_inf_cb;
128
set_monitoring_header_data_cb set_Monitoring_header_data_cb;
129
/*
130
 * connection callbacks 
131
 */
132
receive_connection_cb receive_Connection_cb;
133
connection_failed_cb failed_Connection_cb;
134
/*
135
 * local socketID callback 
136
 */
137
receive_localsocketID_cb receive_SocketID_cb;
138

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

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

    
152
void register_get_recv_pkt_inf(get_recv_pkt_inf_cb recv_pkt_inf_cb)
153
{
154

    
155
    if (recv_pkt_inf_cb == NULL) {
156

    
157
        printf("Register get_recv_pkt_inf_cb failed: NULL ptr  \n");
158

    
159
    } else {
160

    
161
        get_Recv_pkt_inf_cb = recv_pkt_inf_cb;
162

    
163
    }
164
}
165

    
166
void
167
register_set_monitoring_header_pkt_cb(set_monitoring_header_pkt_cb
168
                                      monitoring_header_pkt_cb)
169
{
170

    
171
    if (monitoring_header_pkt_cb == NULL) {
172

    
173
        printf("Register set_monitoring_header_pkt_cb: NULL ptr  \n");
174

    
175
    } else {
176

    
177
        set_Monitoring_header_pkt_cb = monitoring_header_pkt_cb;
178

    
179
    }
180
}
181

    
182
void register_get_recv_data_inf(get_recv_data_inf_cb recv_data_inf_cb)
183
{
184

    
185
    if (recv_data_inf_cb == NULL) {
186

    
187
        printf("Register get_recv_data_inf_cb: NULL ptr  \n");
188

    
189
    } else {
190

    
191
        get_Recv_data_inf_cb = recv_data_inf_cb;
192

    
193
    }
194
}
195

    
196
void register_get_send_data_inf(get_send_data_inf_cb send_data_inf_cb)
197
{
198

    
199
    if (send_data_inf_cb == NULL) {
200

    
201
        printf("Register get_send_data_inf_cb: NULL ptr  \n");
202

    
203
    } else {
204

    
205
        get_Send_data_inf_cb = send_data_inf_cb;
206

    
207
    }
208
}
209

    
210
void
211
register_set_monitoring_header_data_cb(set_monitoring_header_data_cb
212
                                       monitoring_header_data_cb)
213
{
214

    
215
    if (monitoring_header_data_cb == NULL) {
216

    
217
        printf("Register set_monitoring_header_data_cb : NULL ptr  \n");
218

    
219
    } else {
220

    
221
        set_Monitoring_header_data_cb = monitoring_header_data_cb;
222

    
223
    }
224

    
225
}
226

    
227
void register_recv_connection_cb(receive_connection_cb connection_cb)
228
{
229

    
230
    if (connection_cb == NULL) {
231

    
232
        printf("Register receive_connection_cb: NULL ptr  \n");
233

    
234
    } else {
235

    
236
        receive_Connection_cb = connection_cb;
237

    
238
    }
239
}
240

    
241
void
242
register_recv_localsocketID_cb(receive_localsocketID_cb local_socketID_cb)
243
{
244

    
245
    if (local_socketID_cb == NULL) {
246

    
247
        printf("Register receive_localsocketID_cb: NULL ptr \n");
248

    
249
    } else {
250

    
251
        receive_SocketID_cb = local_socketID_cb;
252

    
253
    }
254

    
255

    
256

    
257
}
258

    
259

    
260
void register_error_connection_cb(connection_failed_cb connection_fail)
261
{
262

    
263
    if (connection_fail == NULL) {
264

    
265
        printf("Register connection_failed_cb: NULL ptr  \n");
266

    
267
    } else {
268

    
269
        failed_Connection_cb = connection_fail;
270

    
271
    }
272

    
273
}
274

    
275

    
276
void register_recv_data_cb(receive_data_cb data_cb, unsigned char msgtype)
277
{
278

    
279
    if (msgtype > 126) {
280

    
281
        printf
282
            ("transmissionHandler: Could not register recv_data callback. Msgtype is greater then 126 \n");
283

    
284
    }
285

    
286
    if (data_cb == NULL) {
287

    
288
        printf("Register receive data callback: NUll ptr \n ");
289

    
290
    } else {
291

    
292
        recvcbbuf[msgtype] = data_cb;
293

    
294
    }
295
}
296

    
297
void
298
init_transmissionHandler(boolean recv_data_cb,
299
                         struct timeval timeout_value, const int port,
300
                         const char *ipaddr, const int stun_port,
301
                         const char *stun_ipaddr,
302
                         receive_localsocketID_cb local_socketID_cb,
303
                         void *arg)
304
{
305

    
306
    base = (struct event_base *) arg;
307
    recv_data_callback = recv_data_cb;
308
    setRecvTimeout(timeout_value);
309
    setStunServer(stun_port, stun_ipaddr);
310
    register_recv_localsocketID_cb(local_socketID_cb);
311
    create_socket(port, ipaddr);
312
}
313

    
314
/*
315
 * Sockets 
316
 */
317
/*
318
 * returns a handle to the socketID struct the ipaddr can be a null
319
 * pointer. Then all available ipaddr on the machine are choosen.
320
 */
321
void create_socket(const int port, const char *ipaddr)
322
{
323

    
324
    // int udpSocket = 0;
325
    /*
326
     * libevent2 
327
     */
328
    int i;
329

    
330
    struct sockaddr_in udpaddr;
331
    udpaddr.sin_family = AF_INET;
332
    if (ipaddr == NULL) {
333
        udpaddr.sin_addr.s_addr = htonl(INADDR_ANY);
334
    } else {
335
        udpaddr.sin_addr.s_addr = htonl(inet_addr(ipaddr));
336
    }
337
    udpaddr.sin_port = htons(port);
338
    socketaddrgen udpgen;
339
    udpgen.udpaddr = udpaddr;
340
    local_socketID.internal_addr = udpgen;
341

    
342
    socketfd = createSocket(port, ipaddr);
343

    
344
    struct event *ev;
345
    ev = event_new(base, socketfd, EV_READ | EV_PERSIST, recv_pkg, NULL);
346

    
347
    event_add(ev, NULL);
348

    
349
    /*
350
     * send the NAT traversal STUN request 
351
     */
352
    send_stun_request(socketfd, &stun_server);
353

    
354
    /*
355
     * enter a NAT traversal timeout that takes care of retransmission 
356
     */
357
    struct event *ev1;
358
    struct timeval timeout_value_NAT_traversal = { 2, 0 };
359
    ev1 = evtimer_new(base, nat_traversal_timeout, NULL);
360
    event_add(ev1, &timeout_value_NAT_traversal);
361

    
362
    NAT_traversal = false;
363

    
364
}
365

    
366
void close_socket(socketID_handle socketID)
367
{
368

    
369
    free(socketID);
370

    
371
}
372

    
373
/*
374
 * Connections 
375
 */
376
// the first socketID is the from socketID, the second one is the to
377
// socketID
378

    
379
int
380
open_connection(socketID_handle external_socketID, int *connectionID,
381
                receive_connection_cb connection_cb, void *arg)
382
{
383

    
384
    if (external_socketID == NULL) {
385

    
386
        printf("cannot open connection: one of the socketIDs is NULL \n");
387
        return 0;
388

    
389
    } else if (NAT_traversal == false) {
390

    
391
        printf
392
            ("cannot open connection: NAT traversal for socketID still in progress  \n");
393
        return 0;
394

    
395
    } else if (connection_cb == NULL) {
396

    
397
        printf("cannot open connection: connection_cb is NULL \n");
398
        return 0;
399

    
400
    } else {
401

    
402
        // include pmtu discovery
403
        pmtu pmtu_size = max;
404
        msgtypes msgtype = invite;
405
        char msgbuf[max];
406
        int i = 0;
407
        int seqnr = 0;
408
        boolean setEntry = false;
409

    
410
        // check if that connection already exist
411
        int exist = connection_exist(external_socketID);
412

    
413
        // if so check if it is ready to use
414
        if (exist != -1) {
415

    
416
            int ready = get_connection_status(exist);
417

    
418
            // if so use the callback immidiatley
419
            if (ready == 0) {
420

    
421
                (connection_cb) (exist, arg);
422

    
423
            }
424
            // otherwise just write the connection cb and the arg pointer
425
            // into the connection struct
426
            else {
427
                        receive_connection_cb_list *temp;
428
                        temp = malloc(sizeof(receive_connection_cb_list));
429
                        temp->next = connectbuf[i]->connection_last;
430
                        temp->connection_cb = connection_cb;
431
                        temp->arg = arg;
432
                        connectbuf[i]->connection_last = temp;
433
            }
434

    
435
        } else {
436
            // make entry in connection_establishment array
437
            for (i = 0; i < CONNECTBUFSIZE; i++) {
438

    
439

    
440
                boolean internal_connect_ = false;
441

    
442

    
443
                int check_ext_addr =
444
                    compare_external_address_socketIDs(external_socketID,
445
                                                       &local_socketID);
446

    
447
                if (check_ext_addr == 0) {
448

    
449
                    internal_connect_ = true;
450

    
451
                }
452

    
453
                if (connectbuf[i] == NULL) {
454
                    connectbuf[i] = (connect_data *) malloc(sizeof(connect_data));
455
                    connectbuf[i]->starttime = time(NULL);
456
                    connectbuf[i]->external_socketID = external_socketID;
457
                    connectbuf[i]->pmtutrysize = pmtu_size;
458
                    connectbuf[i]->pmtusize = pmtu_size;
459
                    connectbuf[i]->status = msgtype;
460
                    connectbuf[i]->seqnr = seqnr;
461
                    connectbuf[i]->internal_connect = internal_connect_;
462
                    /*
463
                     * timeout values for the pmtu discovery 
464
                     */
465
                    connectbuf[i]->timeout_value.tv_sec = 15;
466
                    connectbuf[i]->timeout_value.tv_usec = 0;
467
                    connectbuf[i]->connectionID = i;
468
                    *connectionID = i;
469
                    setEntry = true;
470

    
471
                         connectbuf[i]->connection_head = connectbuf[i]->connection_last = malloc(sizeof(receive_connection_cb_list));
472
                         connectbuf[i]->connection_last->next = NULL;
473
                         connectbuf[i]->connection_last->connection_cb = connection_cb;
474
                         connectbuf[i]->connection_last->arg = arg;
475

    
476
                    break;
477
                }
478

    
479
            }
480
        }
481
        if (setEntry == false) {
482

    
483
            printf
484
                ("transmissionHandler:  Could not open connection: Connbuffer full \n ");
485

    
486
        }
487
        // create and send a connection message
488
        create_conn_msg(msgbuf, pmtu_size, *connectionID, 0,
489
                        &local_socketID, external_socketID, msgtype);
490

    
491
        send_conn_msg(*connectionID, msgbuf, pmtu_size);
492

    
493
        struct event *ev;
494
        ev = evtimer_new(base, pmtu_timeout_cb, (void *) connectbuf[i]);
495
        event_add(ev, &connectbuf[*connectionID]->timeout_value);
496

    
497
        return 1;
498
    }
499
}
500

    
501
void close_connection(const int connectionID)
502
{
503

    
504
    // remove it from the connection array
505
    free(connectbuf[connectionID]);
506

    
507
}
508

    
509
void keep_connection_alive(const int connectionID)
510
{
511

    
512
    // to be done with the NAT traversal
513
    // send a message over the wire
514
    printf("\n");
515

    
516
}
517

    
518
int
519
send_all_data(const int connectionID, send_all_data_container * container,
520
              int nr_entries, unsigned char msgtype, send_params * sParams)
521
{
522

    
523

    
524

    
525
    if (nr_entries < 1 || nr_entries > 5) {
526

    
527
        printf
528
            ("send_all_data error: nr_enties is not between 1 and 5 \n ");
529
        return 0;
530

    
531
    } else {
532

    
533
        if (nr_entries == 1) {
534

    
535
            send_data(connectionID, container->buffer_1,
536
                      container->length_1, msgtype, sParams);
537

    
538
            return 1;
539

    
540
        } else if (nr_entries == 2) {
541

    
542
            int buflen = container->length_1 + container->length_2;
543
            char buf[buflen];
544
            memcpy(buf, container->buffer_1, container->length_1);
545
            memcpy(&buf[container->length_1], container->buffer_2,
546
                   container->length_2);
547
            send_data(connectionID, buf, buflen, msgtype, sParams);
548

    
549
            return 1;
550

    
551
        } else if (nr_entries == 3) {
552

    
553
            int buflen =
554
                container->length_1 + container->length_2 +
555
                container->length_3;
556
            char buf[buflen];
557
            memcpy(buf, container->buffer_1, container->length_1);
558
            memcpy(&buf[container->length_1], container->buffer_2,
559
                   container->length_2);
560
            memcpy(&buf[container->length_2], container->buffer_3,
561
                   container->length_3);
562
            send_data(connectionID, buf, buflen, msgtype, sParams);
563

    
564

    
565
            return 1;
566

    
567
        } else if (nr_entries == 4) {
568

    
569
            int buflen =
570
                container->length_1 + container->length_2 +
571
                container->length_3 + container->length_4;
572
            char buf[buflen];
573
            memcpy(buf, container->buffer_1, container->length_1);
574
            memcpy(&buf[container->length_1], container->buffer_2,
575
                   container->length_2);
576
            memcpy(&buf[container->length_2], container->buffer_3,
577
                   container->length_3);
578
            memcpy(&buf[container->length_3], container->buffer_4,
579
                   container->length_4);
580
            send_data(connectionID, buf, buflen, msgtype, sParams);
581

    
582
            return 1;
583

    
584
        } else {
585

    
586
            int buflen =
587
                container->length_1 + container->length_2 +
588
                container->length_3 + container->length_4 +
589
                container->length_5;
590
            char buf[buflen];
591
            memcpy(buf, container->buffer_1, container->length_1);
592
            memcpy(&buf[container->length_1], container->buffer_2,
593
                   container->length_2);
594
            memcpy(&buf[container->length_2], container->buffer_3,
595
                   container->length_3);
596
            memcpy(&buf[container->length_3], container->buffer_4,
597
                   container->length_4);
598
            memcpy(&buf[container->length_4], container->buffer_5,
599
                   container->length_5);
600
            send_data(connectionID, buf, buflen, msgtype, sParams);
601

    
602
            return 1;
603
        }
604

    
605
    }
606

    
607

    
608
}
609

    
610
/*
611
 * send an entire block of data 
612
 */
613
void
614
send_data(const int connectionID, char *sendbuf, int bufsize,
615
          unsigned char msgtype, send_params * sParams)
616
{
617

    
618
    if (sParams == NULL) {
619

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

    
622
    } else {
623

    
624
        // set the messagetype
625
        char packettype = msgtype;
626

    
627
        // get these variables from the connection
628
        socketID_handle local_socketID;
629
        socketID_handle external_socketID;
630
        int udpSocket;
631
        pmtu frag_size;
632
        int sendCounter = 0;
633
        // create some data for the monitoring header
634
        // The messaging layer header requires 13 bytes
635
        unsigned int dataID = 0;
636
        unsigned int offset = 0;
637
        unsigned int datasize = 0;
638
        /*
639
         * The monitoring header type has a range from 0 to 3
640
         * The numbers determine if a monitoring packet hader / monitoring data header is present
641
         *                                                                                   
642
         *     monitoring header type | data header | pkt header                                  
643
         *     -------------------------------------------------                        
644
         *               0            |     No      |    No                                
645
         *               1            |     Yes     |    No                               
646
         *               2            |     No      |    Yes                           
647
         *               3            |     Yes     |    Yes         
648
         */
649
        char monitoringHeaderType = 0;
650
        char monitoringPktHeader[MON_PACKET_HEADER_SIZE];
651
        char monitoringDataHeader[MON_DATA_HEADER_SIZE];
652
        int monitoring_data_header_set = 0;
653
        int monitoring_pkt_header_set = 0;
654
        int size_sendbuf_monitoring_header =
655
            bufsize + MON_DATA_HEADER_SIZE;
656
        char
657
         sendbuf_monitoring_header[size_sendbuf_monitoring_header];
658

    
659
        // a callback to the monitoring module if a data header should be
660
        // set
661
        send_pkt_type_and_dst_inf s_pkt_inf;
662

    
663
        s_pkt_inf.remote_socketID =
664
            connectbuf[connectionID]->external_socketID;
665
        s_pkt_inf.msgtype = msgtype;
666

    
667
        monitoring_data_header_set =
668
            (set_Monitoring_header_data_cb) (monitoringDataHeader,
669
                                             &s_pkt_inf);
670

    
671
        // set the monitoringHeaderType accordingly
672
        if (monitoring_data_header_set == 1) {
673
            monitoringHeaderType = 1;
674

    
675
            // increase the size of the buffer
676
            printf("transmissionHandler: set the monitoring module data header \n  ");
677
            char bufcpy[bufsize];
678
            memcpy(bufcpy, sendbuf, bufsize);
679
            printf("bufsize old: %d \n ", bufsize);
680
            memcpy(sendbuf_monitoring_header, monitoringDataHeader,
681
                   MON_DATA_HEADER_SIZE);
682
            memcpy(&sendbuf_monitoring_header[MON_DATA_HEADER_SIZE],
683
                   sendbuf, bufsize);
684

    
685
            bufsize += MON_DATA_HEADER_SIZE;
686
            sendbuf = sendbuf_monitoring_header;
687
            printf("transmissionHandler: set the monitoring module data header \n bufsize %d \n",bufsize);
688
        }
689

    
690

    
691
        if (connectionID < 0) {
692
            printf("transmissionHandler: ConnectionID does not exist \n");
693
            exit(1);
694

    
695
        }
696

    
697
        if (connectbuf[connectionID] == NULL) {
698
            printf("transmissionHandler: ConnectionID does not exist \n");
699
            exit(1);
700
        } else if (connectbuf[connectionID]->status != 2) {
701
            printf("transmissionHandler: Connection is not active \n");
702
            exit(1);
703
        }
704

    
705
        int external_connectionID =
706
            connectbuf[connectionID]->external_connectionID;
707

    
708
        external_socketID = connectbuf[connectionID]->external_socketID;
709

    
710
        int pmtusize = connectbuf[connectionID]->pmtusize;
711

    
712
        // printf("pmtusize %d \n ",pmtusize);
713

    
714
        if (monitoring_data_header_set == 1)
715
            frag_size = pmtusize - MON_PACKET_HEADER_SIZE;
716
        else
717
            frag_size = pmtusize;
718

    
719
        int messaginglayerpayloadsize = frag_size - MSGL_HEADER_SIZE;
720

    
721
        printf("..messaginglayerpayload %d \n", messaginglayerpayloadsize);
722

    
723
        udpSocket = socketfd;
724
        socketaddrgen udpgen;
725
        if (external_socketID != NULL) {
726
            udpgen = external_socketID->external_addr;
727
        } else {
728
            udpgen = external_socketID->internal_addr;
729
        }
730
        struct sockaddr_in socketaddr = udpgen.udpaddr;
731

    
732
        // set the data ID
733
        dataID = connectbuf[connectionID]->seqnr;
734
        connectbuf[connectionID]->seqnr = dataID + 1;
735
        datasize = bufsize;
736

    
737
        /*
738
         * create a buffer that contains the messaging layer header and
739
         * the payload fragment char packetbuffer[fragmentsize];
740
         * bzero(packetbuffer,fragmentsize); 
741
         */
742
        char *bufptr = NULL;
743
        bufptr = sendbuf;
744

    
745
        /*
746
         * The sending loop aka fragmentation 
747
         */
748
        while (sendCounter < bufsize) {
749

    
750
            // printf("+++++test loopy \n");
751
            char msgbuf[pmtusize];
752
            bzero(msgbuf, pmtusize);
753
            char *msgbufptr = NULL;
754
            unsigned int netint = 0;
755

    
756
            send_pkt_type_and_dst_inf s_pkt_inf_;
757

    
758
            s_pkt_inf_.remote_socketID = connectbuf[connectionID]->external_socketID;
759
            s_pkt_inf_.msgtype = msgtype;
760

    
761
            /*
762
             * callback to the monitoring module if there is a monitoring
763
             * module header 
764
             */
765
            monitoring_pkt_header_set = (set_Monitoring_header_pkt_cb) (monitoringPktHeader, &s_pkt_inf_);
766

    
767
            // set the monitoringHeaderType accordingly
768
            if (monitoring_pkt_header_set == 1) {
769
                        if (monitoringHeaderType == 0) {
770
                                monitoringHeaderType = 2;
771
                        } else if (monitoringHeaderType == 1) {
772
                                monitoringHeaderType = 3;
773
                        }
774
                 }
775

    
776
            msgbuf[0] = packettype;
777
            char pkttype[2];
778
            pkttype[0] = packettype;
779
            pkttype[1] = '\0';
780
            printf("transmissionHandler: the packet type is %s\n", pkttype);
781

    
782
            // enter the messaging layer integers
783
            netint = external_connectionID;
784
            msgbufptr = &msgbuf[1];
785
            memcpy(msgbufptr, &netint, 4);
786
            printf("transmissionHandler:  the connectionID of the other peer is %i\n", external_connectionID);
787

    
788
            netint = dataID;
789
            msgbufptr = &msgbuf[5];
790
            memcpy(msgbufptr, &netint, 4);
791
            printf("transmissionHandler:  the dataID is %i\n", dataID);
792

    
793
            netint = 0;
794
            netint = offset;
795
            msgbufptr = &msgbuf[9];
796
            memcpy(msgbufptr, &netint, 4);
797
            printf("transmissionHandler:  the offset is %i\n", offset);
798

    
799
            netint = 0;
800
            netint = datasize;
801
            msgbufptr = &msgbuf[13];
802
            memcpy(msgbufptr, &netint, 4);
803
            printf("transmissionHandler:  the datasize is %i\n", datasize);
804

    
805
            msgbuf[17] = monitoringHeaderType;
806
            sendCounter += messaginglayerpayloadsize;
807

    
808
            if (monitoring_pkt_header_set == 1) {
809
                        msgbufptr = &msgbuf[18];
810
                        memcpy(msgbufptr, monitoringPktHeader,
811
                               MON_PACKET_HEADER_SIZE);
812
                        int msgbufpos = MSGL_HEADER_SIZE + MON_PACKET_HEADER_SIZE;
813
                        msgbufptr = &msgbuf[msgbufpos];
814
                        memcpy(msgbufptr, bufptr, messaginglayerpayloadsize);
815
            } else {
816
                        msgbufptr = &msgbuf[MSGL_HEADER_SIZE];
817
                        memcpy(msgbufptr, bufptr, messaginglayerpayloadsize);
818
            }
819

    
820

    
821
            // check if this is the last fragment and adjust the size
822
            // accordingly
823

    
824
            int sendsize = pmtusize;
825

    
826
            if ((offset + messaginglayerpayloadsize) > datasize) {
827

    
828
                sendsize = datasize - offset + MSGL_HEADER_SIZE;
829

    
830
                if (monitoring_pkt_header_set == 1) {
831

    
832
                    sendsize += MON_PACKET_HEADER_SIZE;
833
                }
834

    
835
                printf("sendsize is %d \n", sendsize);
836
            }
837

    
838

    
839
            char testbuf[sendsize];
840
            memcpy(testbuf, msgbuf, sendsize);
841
            // printf("-=- send data: %s \n ",&testbuf[34]);
842

    
843
            sendPacket(udpSocket, msgbuf, sendsize, &socketaddr,
844
                       pmtu_error_cb_th);
845

    
846
            // printf("-=- send data: %s \n ",msgbuf);
847

    
848

    
849
            // increment the data offset
850
            offset += messaginglayerpayloadsize;
851
            fprintf(stderr, "transmissionHandler: Send a packet! \n");
852

    
853
            // increment the pointer of the buffer for the fragmentsize
854
            bufptr += messaginglayerpayloadsize;
855

    
856

    
857
        }
858

    
859
        printf("transmissionHandler: SENDING FINISHED \n");
860
        /*
861
         * monitoring module callback 
862
         */
863
        mon_data_inf sd_data_inf;
864

    
865
        sd_data_inf.remote_socketID =
866
            connectbuf[connectionID]->external_socketID;
867
        sd_data_inf.buffer = sendbuf;
868
        sd_data_inf.bufSize = bufsize;
869
        sd_data_inf.msgtype = msgtype;
870
        sd_data_inf.monitoringHeaderType = monitoringHeaderType;
871
        sd_data_inf.monitoringDataHeader = monitoringDataHeader;
872
        sd_data_inf.nrFragments =
873
            ceil(bufsize / messaginglayerpayloadsize);
874
        sd_data_inf.priority = sParams->priority;
875
        sd_data_inf.padding = sParams->padding;
876
        sd_data_inf.confirmation = sParams->confirmation;
877
        sd_data_inf.reliable = sParams->reliable;
878
        gettimeofday(&sd_data_inf.arrival_time, NULL);
879

    
880
        (get_Send_data_inf_cb) ((void *) &sd_data_inf);
881

    
882
    }
883

    
884

    
885
}
886

    
887
/*
888
 * recv data with polling 
889
 */
890
int
891
recv_data(const int connectionID, char *recvbuf, int *bufsize,
892
          recv_params * rParams)
893
{
894

    
895
    if (rParams == NULL) {
896

    
897
        printf("recv_data failed: recv_params is a NULL ptr \n ");
898
        return 0;
899

    
900
    } else {
901

    
902
        printf("transmissionhandler: recv data called \n");
903

    
904
        int i = 0;
905
        int returnValue = 0;
906
        double timeout = (double) recv_timeout.tv_sec;
907
        time_t endtime = time(NULL);
908

    
909
        for (i = 0; i < RECVDATABUFSIZE; i++) {
910

    
911
            if (recvdatabuf[i] != NULL) {
912

    
913
                if (recvdatabuf[i]->connectionID == connectionID) {
914

    
915
                    printf("transmissionhandler: recv data has entry  \n");
916

    
917
                    double timepass =
918
                        difftime(endtime, recvdatabuf[i]->starttime);
919

    
920
                    // check if the specified connection has data and it
921
                    // is complete
922
                    // check the data seqnr
923
                    // if(connectionID == recvdatabuf[i]->connectionID &&
924
                    // 1 == recvdatabuf[i]->status){
925

    
926
                    if (1 == recvdatabuf[i]->status) {
927

    
928
                        // printf("transmissionHandler: recv_data set is
929
                        // complete \n" );
930

    
931
                        // printf("debud \n");
932

    
933
                        // exchange the pointers
934
                        int buffersize = 0;
935
                        buffersize = recvdatabuf[i]->bufsize;
936
                        *bufsize = buffersize;
937
                        // recvbuf = recvdatabuf[i]->recvbuf;
938

    
939
                        // printf("buffersize %d \n",buffersize);
940
                        memcpy(recvbuf, recvdatabuf[i]->recvbuf,
941
                               buffersize);
942
                        // printf(" recvbuf %s \n",recvbuf );
943

    
944
                        double nrMissFrags =
945
                            (double) recvdatabuf[i]->nrFragments /
946
                            (double) recvdatabuf[i]->recvFragments;
947
                        int nrMissingFragments = (int) ceil(nrMissFrags);
948

    
949
                        rParams->nrMissingFragments = nrMissingFragments;
950
                        rParams->nrFragments = recvdatabuf[i]->nrFragments;
951
                        rParams->msgtype = recvdatabuf[i]->msgtype;
952
                        rParams->connectionID =
953
                            recvdatabuf[i]->connectionID;
954

    
955
                        // break from the loop
956
                        // printf(" recvbuf %s \n ",recvbuf);
957

    
958
                        // double nrMissFrags =
959
                        // (double)recvdatabuf[i]->nrFragments /
960
                        // (double)recvdatabuf[i]->recvFragments;
961
                        // int nrMissingFragments =
962
                        // (int)ceil(nrMissFrags);
963

    
964
                        mon_data_inf recv_data_inf;
965

    
966
                        recv_data_inf.remote_socketID =
967
                            connectbuf[connectionID]->external_socketID;
968
                        recv_data_inf.buffer = recvdatabuf[i]->recvbuf;
969
                        recv_data_inf.bufSize = recvdatabuf[i]->bufsize;
970
                        recv_data_inf.msgtype = recvdatabuf[i]->msgtype;
971
                        recv_data_inf.monitoringHeaderType =
972
                            recvdatabuf[i]->monitoringHeaderType;
973
                        recv_data_inf.monitoringDataHeader =
974
                            recvdatabuf[i]->monitoringDataHeader;
975
                        gettimeofday(&recv_data_inf.arrival_time, NULL);
976
                        recv_data_inf.firstPacketArrived =
977
                            recvdatabuf[i]->firstPacketArrived;
978
                        recv_data_inf.nrMissingFragments =
979
                            nrMissingFragments;
980
                        recv_data_inf.nrFragments =
981
                            recvdatabuf[i]->nrFragments;
982
                        recv_data_inf.priority = false;
983
                        recv_data_inf.padding = false;
984
                        recv_data_inf.confirmation = false;
985
                        recv_data_inf.reliable = false;
986

    
987
                        // send data recv callback to monitoring module 
988
                        (get_Recv_data_inf_cb) ((void *) rParams);
989

    
990

    
991
                        // free the allocated memory
992
                        free(recvdatabuf[i]);
993
                        recvdatabuf[i] = NULL;
994

    
995
                        returnValue = 1;
996
                        break;
997

    
998
                    }
999

    
1000
                    if (recvdatabuf[i] != NULL) {
1001

    
1002
                        if (timepass > timeout) {
1003

    
1004
                            printf
1005
                                ("transmissionHandler: recv_data timeout called  \n");
1006

    
1007
                            // some data about the missing chunks should
1008
                            // be added here
1009
                            // exchange the pointers 
1010
                            int buffersize = 0;
1011
                            buffersize = recvdatabuf[i]->bufsize;
1012
                            *bufsize = buffersize;
1013
                            // recvbuf = recvdatabuf[i]->recvbuf;
1014

    
1015
                            double nrMissFrags =
1016
                                (double) recvdatabuf[i]->nrFragments /
1017
                                (double) recvdatabuf[i]->recvFragments;
1018
                            int nrMissingFragments =
1019
                                (int) ceil(nrMissFrags);
1020

    
1021
                            // printf(" recvbuf %s \n",recvbuf );
1022

    
1023
                            memcpy(recvbuf, recvdatabuf[i]->recvbuf,
1024
                                   buffersize);
1025

    
1026
                            rParams->nrMissingFragments =
1027
                                nrMissingFragments;
1028
                            rParams->nrFragments =
1029
                                recvdatabuf[i]->nrFragments;
1030
                            rParams->msgtype = recvdatabuf[i]->msgtype;
1031
                            rParams->connectionID =
1032
                                recvdatabuf[i]->connectionID;
1033
                            // free the allocated memory 
1034
                            free(recvdatabuf[i]);
1035
                            recvdatabuf[i] = NULL;
1036

    
1037
                            // send data recv callback to monitoring
1038
                            // module
1039
                            (get_Recv_data_inf_cb) ((void *) rParams);
1040

    
1041
                            returnValue = 1;
1042
                            break;
1043

    
1044
                        }
1045
                    }
1046

    
1047
                }
1048

    
1049
            }
1050
            // printf("2 recvbuf %s \n ",recvbuf);
1051
        }
1052
        return returnValue;
1053
    }
1054
}
1055

    
1056
void setStunServer(const int port, const char *ipaddr)
1057
{
1058

    
1059
    stun_server.sin_family = AF_INET;
1060
    if (ipaddr == NULL) {
1061
        stun_server.sin_addr.s_addr = htonl(INADDR_ANY);
1062
    } else {
1063
        stun_server.sin_addr.s_addr = resolve(ipaddr);
1064
    }
1065
    stun_server.sin_port = htons(port);
1066

    
1067
}
1068

    
1069
void setRecvTimeout(struct timeval timeout_value)
1070
{
1071

    
1072
    recv_timeout = timeout_value;
1073

    
1074
}
1075

    
1076

    
1077
void
1078
create_conn_msg(char *msgbuf, int bufsize, int local_connectionID,
1079
                int external_connectionID, socketID_handle local_socketID,
1080
                socketID_handle external_socketID, int msgtype)
1081
{
1082

    
1083
    char packettype = 127;
1084
    char *msgbufptr = NULL;
1085
    int netint = 0;
1086
    // printf("connectionID %i \n",local_connectionID);
1087

    
1088
    // printf("create_conn_msg: msgtype is %d \n ",msgtype);
1089

    
1090
    switch (msgtype) {
1091
        // invite
1092
    case 0:
1093
        // write that this is a connect message
1094
        msgbuf[0] = packettype;
1095
        // write the messagetype invite
1096
        msgtype = 0;
1097
        msgbufptr = &msgbuf[1];
1098
        memcpy(msgbufptr, &msgtype, 4);
1099
        // write the connectID
1100
        netint = local_connectionID;
1101
        msgbufptr = &msgbuf[5];
1102
        memcpy(msgbufptr, &netint, 4);
1103
        // enter the pmut size
1104
        netint = bufsize;
1105
        msgbufptr = &msgbuf[9];
1106
        memcpy(msgbufptr, &netint, 4);
1107
        // write the socketID
1108
        msgbufptr = &msgbuf[13];
1109
        memcpy(msgbufptr, local_socketID, sizeof(socket_ID));
1110
        break;
1111

    
1112
        // ok
1113
    case 1:
1114
        // write that this is a connect message 
1115
        msgbuf[0] = packettype;
1116
        // write the messagetype ok 
1117
        netint = 1;
1118
        msgbufptr = &msgbuf[1];
1119
        memcpy(msgbufptr, &netint, 4);
1120
        // write the connectID_from
1121
        netint = external_connectionID;
1122
        msgbufptr = &msgbuf[5];
1123
        memcpy(msgbufptr, &netint, 4);
1124
        // write the connectID_to
1125
        netint = local_connectionID;
1126
        msgbufptr = &msgbuf[9];
1127
        memcpy(msgbufptr, &netint, 4);
1128
        // write the pmtu size
1129
        netint = bufsize;
1130
        msgbufptr = &msgbuf[13];
1131
        memcpy(msgbufptr, &netint, 4);
1132
        break;
1133

    
1134
        // ack
1135
    case 2:
1136
        // write that this is a connect message 
1137
        msgbuf[0] = packettype;
1138
        // write the messagetype ack
1139
        netint = 2;
1140
        msgbufptr = &msgbuf[1];
1141
        memcpy(msgbufptr, &netint, 4);
1142
        // write the connectID_from
1143
        netint = local_connectionID;
1144
        msgbufptr = &msgbuf[5];
1145
        memcpy(msgbufptr, &netint, 4);
1146
        // write the connectID_to 
1147
        netint = external_connectionID;
1148
        msgbufptr = &msgbuf[9];
1149
        memcpy(msgbufptr, &netint, 4);
1150
        // write the pmtu size
1151
        netint = bufsize;
1152
        msgbufptr = &msgbuf[13];
1153
        memcpy(msgbufptr, &netint, 4);
1154
        break;
1155
    }
1156

    
1157
}
1158

    
1159
void send_conn_msg(const int connectionID, char *msgbuf, int bufsize)
1160
{
1161

    
1162
    int udpSocket;
1163
    int returnValue;
1164
    socketID_handle external_socketID;
1165
    pmtu frag_size;
1166
    boolean int_connect;
1167

    
1168
    // printf("connectionID %i \n",connectionID);
1169
    // printf("bufsize %i \n",bufsize);
1170

    
1171

    
1172
    // set the socket variables
1173
    int_connect = connectbuf[connectionID]->internal_connect;
1174
    external_socketID = connectbuf[connectionID]->external_socketID;
1175

    
1176
    if (bufsize > 0) {
1177
        frag_size = bufsize;
1178
    } else {
1179

    
1180
        frag_size = max;
1181
    }
1182
    // 
1183
    udpSocket = socketfd;
1184

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

    
1187
    // socketaddrgen udpgen = external_socketID->external_addr;
1188
    socketaddrgen udpgen;
1189

    
1190

    
1191
    if (int_connect == false) {
1192
        udpgen = external_socketID->external_addr;
1193
        // set the host order
1194
        // struct sockaddr_in udpaddr;
1195
        // udpaddr = external_socketID->external_addr.udpaddr;
1196
        // udpaddr.sin_addr.s_addr = htonl(udpaddr.sin_addr.s_addr);
1197
        // udpaddr.sin_port = htons(udpaddr.sin_port);
1198
        // udpgen.udpaddr = udpaddr;
1199
        // external_socketID->external_addr = udpgen;
1200
    } else {
1201
        udpgen = external_socketID->internal_addr;
1202
        // set the host order
1203
        // struct sockaddr_in udpaddr;
1204
        // udpaddr = external_socketID->internal_addr.udpaddr;
1205
        // udpaddr.sin_addr.s_addr = htonl(udpaddr.sin_addr.s_addr);
1206
        // udpaddr.sin_port = htons(udpaddr.sin_port);
1207
        // udpgen.udpaddr = udpaddr;
1208
        // external_socketID->internal_addr = udpgen;
1209
    }
1210

    
1211

    
1212
    struct sockaddr_in udpaddr;
1213
    udpaddr = udpgen.udpaddr;
1214

    
1215
    printf("transmissionHandler: send_conn: the port is %i  \n",
1216
           ntohs(udpaddr.sin_port));
1217
    printf("transmissionHandler: send_conn: the pmtu is %i  \n",
1218
           frag_size);
1219

    
1220
    sendPacket(udpSocket, msgbuf, frag_size, &udpgen.udpaddr,
1221
               pmtu_error_cb_th);
1222

    
1223
}
1224

    
1225
void
1226
recv_conn_msg(socketID_handle local_socketID, char *msgbuf, int bufsize)
1227
{
1228

    
1229
    char *msgbufptr = NULL;
1230
    int connmsgtype = 0;
1231
    int i = 0;
1232
    int pmtusize = 0;
1233
    // socketaddr *socketID_to_ptr = NULL; 
1234
    int msgtypo = 0;
1235
    char msgbufnew[bufsize];
1236
    int internal_connectionID = 0;
1237
    socketID_handle external_socketID;
1238
    int external_connectionID = 0;
1239
    int connExist = 0;
1240
    time_t now = time(NULL);
1241
    double timediff = 0.0;
1242

    
1243
    // extract the msgtype
1244
    msgbufptr = &msgbuf[1];
1245
    memcpy(&connmsgtype, msgbufptr, 4);
1246

    
1247
    // check the connection messagetype
1248
    switch (connmsgtype) {
1249

    
1250
        /*
1251
         * if invite: enter a new socket make new entry in connect array
1252
         * send an ok 
1253
         */
1254
    case 0:
1255
        // create a ptr to a socketaddr and allocate memory
1256
        // socketID_to_ptr = (socketaddr *)malloc(sizeof(socketaddr));
1257
        // copy the socketaddr from the message
1258

    
1259

    
1260
        // extract the pmtu size
1261
        msgbufptr = &msgbuf[9];
1262
        memcpy(&pmtusize, msgbufptr, 4);
1263

    
1264

    
1265
        msgbufptr = &msgbuf[13];
1266
        external_socketID = malloc(sizeof(socket_ID));
1267
        memcpy(external_socketID, msgbufptr, sizeof(socket_ID));
1268

    
1269
        /*
1270
         * debug info 
1271
         */
1272
        printf("transmissionHandler: __________________ \n ");
1273
        printf("transmissionHandler: received invite \n ");
1274

    
1275
        // ::add check if socketID is already known
1276

    
1277
        msgbufptr = &msgbuf[5];
1278
        memcpy(&external_connectionID, msgbufptr, 4);
1279

    
1280
        socketaddrgen udpgen;
1281
        udpgen = external_socketID->external_addr;
1282
        struct sockaddr_in udpaddr;
1283
        udpaddr = external_socketID->external_addr.udpaddr;
1284
        // printf("+++port is %d \n",udpaddr.sin_port);
1285

    
1286
        udpaddr.sin_addr.s_addr = htonl(udpaddr.sin_addr.s_addr);
1287
        udpaddr.sin_port = htons(udpaddr.sin_port);
1288
        udpgen.udpaddr = udpaddr;
1289
        external_socketID->external_addr = udpgen;
1290

    
1291
        /*
1292
         * check if another connection for the external connectionID exist 
1293
         * that was established within the last 2 seconds 
1294
         */
1295
        for (i = 0; i < CONNECTBUFSIZE; i++) {
1296

    
1297
            if (connectbuf[i] != NULL) {
1298

    
1299
                if (compare_socketIDs
1300
                    (connectbuf[i]->external_socketID,
1301
                     external_socketID) == 0) {
1302

    
1303
                    timediff = difftime(now, connectbuf[i]->starttime);
1304
                    if (timediff < 2) {
1305
                        connExist = 1;
1306
                    }
1307

    
1308
                }
1309
            }
1310
        }
1311

    
1312

    
1313
        if (connExist == 0) {
1314

    
1315
            // create an entry in the connecttrybuf 
1316
            for (i = 0; i < CONNECTBUFSIZE; i++) {
1317

    
1318
                if (connectbuf[i] == NULL) {
1319

    
1320
                    connectbuf[i] = (connect_data *) malloc(sizeof(connect_data));
1321
                         connectbuf[i]->connection_head = connectbuf[i]->connection_last = NULL;
1322
                    connectbuf[i]->starttime = time(NULL);
1323
                    connectbuf[i]->external_socketID = external_socketID;
1324
                    connectbuf[i]->pmtusize = pmtusize;
1325
                    connectbuf[i]->status = 1;
1326
                    connectbuf[i]->external_connectionID = external_connectionID;
1327
                    internal_connectionID = i;
1328
                    break;
1329
                }
1330

    
1331
            }
1332

    
1333
            // create and send the ok conn message 
1334
            msgtypo = 1;
1335
            // printf("internal connectionID %d \n",
1336
            // internal_connectionID);
1337
            create_conn_msg(msgbufnew, pmtusize, internal_connectionID,
1338
                            external_connectionID, NULL, NULL, msgtypo);
1339

    
1340
            send_conn_msg(internal_connectionID, msgbufnew, pmtusize);
1341

    
1342
            break;
1343

    
1344
        } else {
1345

    
1346
            break;
1347
        }
1348
        /*
1349
         * if ok: find the entry in the connectiontry array create/send an 
1350
         * ack make an entry in the connection array delete the entry in
1351
         * the connection_try array 
1352
         */
1353
    case 1:
1354
        printf("transmissionHandler: __________________ \n ");
1355
        printf("transmissionHandler: received ok \n ");
1356

    
1357
        // extract the connect_try array position 
1358
        msgbufptr = &msgbuf[9];
1359
        memcpy(&external_connectionID, msgbufptr, 4);
1360
        printf("transmissionHandler: external connectionID %i \n",
1361
               external_connectionID);
1362

    
1363
        // extract pmtu size
1364
        msgbufptr = &msgbuf[13];
1365
        memcpy(&pmtusize, msgbufptr, 4);
1366
        printf("transmissionHandler: pmtusize %i \n", pmtusize);
1367
        // extract the connecttry_ID_to
1368

    
1369
        msgbufptr = &msgbuf[5];
1370
        memcpy(&internal_connectionID, msgbufptr, 4);
1371
        printf("transmissionHandler: internal connectionID %i \n",
1372
               internal_connectionID);
1373

    
1374
        /*
1375
         * check if the connection status is not already 1 or 2 
1376
         */
1377
        if (connectbuf[internal_connectionID]->status == 0) {
1378

    
1379
            // set the external connectionID
1380
            connectbuf[internal_connectionID]->external_connectionID =
1381
                external_connectionID;
1382

    
1383
            // change status in the connection_data
1384
            connectbuf[internal_connectionID]->status = 2;
1385

    
1386
            // change pmtusize in the connection_data
1387
            connectbuf[internal_connectionID]->pmtusize = pmtusize;
1388
            connectbuf[internal_connectionID]->pmtutrysize = pmtusize;
1389

    
1390
            if (receive_Connection_cb != NULL)
1391
                (receive_Connection_cb) (internal_connectionID, NULL);
1392

    
1393

    
1394
                 while(connectbuf[internal_connectionID]->connection_head != NULL) {
1395
                        receive_connection_cb_list *temp;
1396
                        temp = connectbuf[internal_connectionID]->connection_head;
1397
                        (temp->connection_cb) (internal_connectionID, temp->arg);
1398
                        connectbuf[internal_connectionID]->connection_head = temp->next;
1399
                        free(temp);
1400
            }
1401
                  connectbuf[internal_connectionID]->connection_head = connectbuf[internal_connectionID]->connection_last = NULL;
1402

    
1403
            // change the status
1404
            // connectbuf[internal_connectionID]->status = 2;
1405

    
1406
            // extrackt the socketID
1407
            // internal_socketID = connectbuf[internal_connectionID]-> ;
1408

    
1409
            // send the ack
1410
            msgtypo = 2;
1411
            create_conn_msg(msgbufnew, pmtusize, internal_connectionID,
1412
                            external_connectionID, NULL, NULL, msgtypo);
1413
            send_conn_msg(internal_connectionID, msgbufnew, pmtusize);
1414
            printf
1415
                ("transmissionHandler: active connection established \n");
1416
            // connection_establisched(connectionID_this_peer);
1417

    
1418
            break;
1419

    
1420
        } else {
1421

    
1422
            break;
1423
        }
1424

    
1425
        /*
1426
         * if ack: find the entry in the connection array set the
1427
         * connection active change the pmtu size 
1428
         */
1429
    case 2:
1430
        printf("transmissionHandler: __________________ \n ");
1431
        printf("transmissionHandler: received ack \n ");
1432

    
1433
        // extract the connect_try array position 
1434
        msgbufptr = &msgbuf[9];
1435
        memcpy(&internal_connectionID, msgbufptr, 4);
1436

    
1437
        // extract pmtu size
1438
        msgbufptr = &msgbuf[13];
1439
        memcpy(&pmtusize, msgbufptr, 4);
1440

    
1441
        printf("internal connectionID: %d \n", internal_connectionID);
1442
        printf("connection status : %d \n",
1443
               connectbuf[internal_connectionID]->status);
1444

    
1445
        /*
1446
         * checks if the connection is not already established 
1447
         */
1448
        if (connectbuf[internal_connectionID]->status == 1) {
1449

    
1450
            // change status of the connection
1451
            connectbuf[internal_connectionID]->status = 2;
1452

    
1453
            // change pmtusize
1454
            connectbuf[internal_connectionID]->pmtusize = pmtusize;
1455

    
1456
            printf
1457
                ("transmissionHandler: passiv connection established \n");
1458

    
1459
            if (receive_Connection_cb != NULL)
1460
                (receive_Connection_cb) (internal_connectionID, NULL);
1461

    
1462
                 while(connectbuf[internal_connectionID]->connection_head != NULL) {
1463
                        receive_connection_cb_list *temp;
1464
                        temp = connectbuf[internal_connectionID]->connection_head;
1465
                        (temp->connection_cb) (internal_connectionID, temp->arg);
1466
                        connectbuf[internal_connectionID]->connection_head = temp->next;
1467
                        free(temp);
1468
            }
1469
                 connectbuf[internal_connectionID]->connection_head = connectbuf[internal_connectionID]->connection_last = NULL;
1470
            // connection_establisched(connectionID_this_peer);
1471
            // printf("going here \n ");
1472
            // main_callback(0);
1473
            break;
1474

    
1475
        } else {
1476

    
1477
            break;
1478

    
1479
        }
1480
    }
1481

    
1482
}
1483

    
1484
/*
1485
 * what to do once a packet arrived if it is a conn packet send it to
1486
 * recv_conn handler if it is a data packet send it to the recv_data
1487
 * handler 
1488
 */
1489

    
1490
// get the file descriptor directly
1491

    
1492
void recv_pkg(int fd, short event, void *arg)
1493
{
1494

    
1495
    printf("transmissionHandler: recv_pkg is called \n ");
1496

    
1497
    pmtu pkgsize = max;
1498
    char msgbuf[pkgsize];
1499
    int ttl;
1500
    struct sockaddr_in recv_addr;
1501
    // int rt = 0;
1502
    int recvSize;
1503

    
1504
    recvPacket(fd, msgbuf, &recvSize, &recv_addr, pmtu_error_cb_th, &ttl);
1505

    
1506
    // check if it is not just an error message
1507
    if (ttl != -1) {
1508

    
1509
        unsigned short stun_bind_response = 0x0101;
1510
        unsigned short msgspot;
1511
        memcpy(&msgspot, msgbuf, sizeof(unsigned short));
1512
        char packettype;
1513
        StunMessage stunmsg;
1514
        packettype = msgbuf[0];
1515

    
1516
        if (msgspot == stun_bind_response) {
1517

    
1518
            printf
1519
                ("transmissionHandler: recv_pkg: parse stun message is called \n");
1520

    
1521
            recv_stun_msg(msgbuf, recvSize);
1522

    
1523
        } else if (packettype == 127) {
1524
            // send it of to the handler
1525

    
1526
            printf("transmissionHandler: received conn pkg \n ");
1527

    
1528
            recv_conn_msg(&local_socketID, msgbuf, recvSize);
1529

    
1530
        } else if (packettype < 127) {
1531

    
1532
            // need to check if this is really a data message 
1533

    
1534
            printf("transmissionHandler: received data pkg \n ");
1535

    
1536
            recv_data_msg(msgbuf, recvSize, ttl);
1537

    
1538
        }
1539
        // printf("recv_pkg is done \n ");
1540
    } else {
1541

    
1542
        printf
1543
            ("transmissionHandler: recv_pkg got only unrelated error \n ");
1544
    }
1545

    
1546

    
1547
}
1548

    
1549
void recv_stun_msg(char *msgbuf, int recvSize)
1550
{
1551

    
1552
    /*
1553
     * create empty stun message struct 
1554
     */
1555
    StunMessage resp;
1556
    memset(&resp, 0, sizeof(StunMessage));
1557
    /*
1558
     * parse the message 
1559
     */
1560
    int returnValue = 0;
1561
    returnValue = recv_stun_message(msgbuf, recvSize, &resp);
1562

    
1563
    if (returnValue == 0) {
1564
        /*
1565
         * read the reflexive Address into the local_socketID 
1566
         */
1567
        struct sockaddr_in reflexiveAddr;
1568
        reflexiveAddr.sin_family = AF_INET;
1569
        reflexiveAddr.sin_addr.s_addr = resp.mappedAddress.ipv4.addr;
1570
        reflexiveAddr.sin_port = resp.mappedAddress.ipv4.port;
1571
        socketaddrgen reflexiveAddres;
1572
        reflexiveAddres.udpaddr = reflexiveAddr;
1573
        local_socketID.external_addr = reflexiveAddres;
1574
        NAT_traversal = true;
1575

    
1576
        /*
1577
         * just debug 
1578
         */
1579
        UInt32 ip_addr = reflexiveAddr.sin_addr.s_addr;
1580
        char mapped_addr[16];
1581
        sprintf(mapped_addr, "%d.%d.%d.%d", (ip_addr >> 24) & 0xff,
1582
                (ip_addr >> 16) & 0xff, (ip_addr >> 8) & 0xff,
1583
                ip_addr & 0xff);
1584

    
1585
        printf("transmissionHandler: mapped Address %s port %i \n ",
1586
               mapped_addr, reflexiveAddr.sin_port);
1587

    
1588
    }
1589
    // callback to the upper layer indicating that the socketID is now
1590
    // ready to use
1591
    (receive_SocketID_cb) (&local_socketID, 0);
1592

    
1593
}
1594

    
1595
// process a singe recv data message
1596
void recv_data_msg(char *msgbuf, int bufsize, int ttl)
1597
{
1598

    
1599
    printf("transmissionHandler: received data message \n");
1600

    
1601
    int local_connectionID;
1602
    int seqnr;
1603
    int offset;
1604
    int size;
1605
    char *msgbufptr = NULL;
1606
    int i = 0;
1607
    boolean _bool = FALSE;
1608
    char msgtype;
1609
    /*
1610
     * The monitoring header type has a range from 0 to 3
1611
     * The numbers determine if a monitoring packet hader / monitoring data header is present
1612
     * 
1613
     *     monitoring header type | data header | pkt header
1614
     *     -------------------------------------------------
1615
     *               0            |     No      |    No
1616
     *               1            |     Yes     |    No
1617
     *               2            |     No      |    Yes
1618
     *               3            |     Yes     |    Yes
1619
     */
1620

    
1621
    char monitoringHeaderType = 0;
1622
    char monitoringPktHeader[MON_PACKET_HEADER_SIZE];
1623
    char monitoringDataHeader[MON_DATA_HEADER_SIZE];
1624
    int monitoring_data_header_set = 0;
1625
    int monitoring_pkt_header_set = 0;
1626

    
1627
    // extract msgtype
1628
    msgbufptr = &msgbuf[0];
1629
    memcpy(&msgtype, msgbufptr, 1);
1630
    printf("msgtype %d \n", msgtype);
1631

    
1632
    // extract connectionID
1633
    msgbufptr = &msgbuf[1];
1634
    memcpy(&local_connectionID, msgbufptr, 4);
1635
    printf("local_connectionID %d \n", local_connectionID);
1636

    
1637
    // extract seqnrg
1638
    msgbufptr = &msgbuf[5];
1639
    memcpy(&seqnr, msgbufptr, 4);
1640
    printf("seqnr %d \n", seqnr);
1641

    
1642
    // data offset
1643
    msgbufptr = &msgbuf[9];
1644
    memcpy(&offset, msgbufptr, 4);
1645
    printf("offset is %d \n", offset);
1646

    
1647
    char firstPacketArrived = 0;
1648
    if (offset == 0)
1649
                firstPacketArrived = 1;
1650

    
1651
    // size 
1652
    msgbufptr = &msgbuf[13];
1653
    memcpy(&size, msgbufptr, 4);
1654
    printf("size is %d \n", size);
1655

    
1656
    // hasMonitoringHeader
1657
    msgbufptr = &msgbuf[17];
1658
    memcpy(&monitoringHeaderType, msgbufptr, 1);
1659
    printf("monitoring header type %d \n ", monitoringHeaderType);
1660

    
1661
    if (monitoringHeaderType == 2 || monitoringHeaderType == 3) {
1662
                msgbufptr = &msgbuf[18];
1663
                memcpy(monitoringPktHeader, msgbufptr, MON_PACKET_HEADER_SIZE);
1664
    }
1665
    // check if a recv_data exist and enter data
1666
    for (i = 0; i < RECVDATABUFSIZE; i++) {
1667

    
1668
         if (recvdatabuf[i] != NULL) {
1669

    
1670
           if (local_connectionID == recvdatabuf[i]->connectionID && seqnr == recvdatabuf[i]->seqnr) {
1671

    
1672
                        printf("connID %d\n", recvdatabuf[i]->connectionID);
1673
                        printf("seqnr %d\n", recvdatabuf[i]->seqnr);
1674

    
1675
                        if (firstPacketArrived = 1) {
1676
                                recvdatabuf[i]->firstPacketArrived = 1;
1677
                }
1678
                        // increment fragmentnr
1679
                        recvdatabuf[i]->recvFragments = recvdatabuf[i]->recvFragments + 1;
1680
                        int fragmentsize = connectbuf[local_connectionID]->pmtusize - MSGL_HEADER_SIZE;
1681
                        char *bufptr = NULL;
1682
                        bufptr = recvdatabuf[i]->recvbuf;
1683
                        bufptr += offset;
1684
                        // enter the data into the buffer
1685
                        int cpysize = fragmentsize;
1686

    
1687
                        // check for last fragment
1688
                        if (recvdatabuf[i]->nrFragments == recvdatabuf[i]->recvFragments) {
1689
                        cpysize = recvdatabuf[i]->bufsize - offset;
1690
                }
1691
                        // adapt copy size for the last fragment without
1692
                        // monitoring header
1693
                        if (monitoringHeaderType == 0 || monitoringHeaderType == 1) {
1694
                        // adapt copy size for the last fragment with the
1695
                        // monitoring header
1696
                        msgbufptr = &msgbuf[18];
1697
                        memcpy(bufptr, msgbufptr, cpysize);
1698
                        } else if (monitoringHeaderType == 2 || monitoringHeaderType == 3) {
1699
                        int bufpos = MSGL_HEADER_SIZE + MON_PACKET_HEADER_SIZE;
1700
                        printf("bufpos %d \n", bufpos);
1701
                        msgbufptr = &msgbuf[bufpos];
1702
                        // cpysize = cpysize + MON_PACKET_HEADER_SIZE;
1703
                        printf("cpyssize %d \n", cpysize);
1704
                        memcpy(bufptr, msgbufptr, cpysize);
1705
                }
1706

    
1707
                        _bool = TRUE;
1708

    
1709
                        /*
1710
                         * all fragments arrived and it are multiple fragments 
1711
                         */
1712

    
1713
                        if (recvdatabuf[i]->nrFragments == recvdatabuf[i]->recvFragments) {
1714
                                if (firstPacketArrived = 1) {
1715
                                recvdatabuf[i]->firstPacketArrived = 1;
1716
                        }
1717

    
1718
                                printf("set the status of recvbuf 1  \n");
1719
                                recvdatabuf[i]->status = 1;
1720

    
1721
                                // extract the monitoring module data header
1722
                                if (monitoringHeaderType == 1 || monitoringHeaderType == 3) {
1723
                                memcpy(monitoringDataHeader, recvdatabuf[i]->recvbuf, MON_DATA_HEADER_SIZE);
1724

    
1725
                        // shorten the recv buffer and change the
1726
                        // buffersize
1727
                                recvdatabuf[i]->recvbuf += MON_DATA_HEADER_SIZE;
1728
                                recvdatabuf[i]->bufsize -= MON_DATA_HEADER_SIZE;
1729
                                recvdatabuf[i]->monitoringDataHeader = monitoringDataHeader;
1730
                        }
1731

    
1732
                                if (recv_data_callback) {
1733

    
1734
                                        // get the msgtype
1735
                                        char msgtype = recvdatabuf[i]->msgtype;
1736

    
1737
                                        // get the right callback
1738
                                        receive_data_cb receive_data_callback = recvcbbuf[msgtype];
1739
                                        bufptr = recvdatabuf[i]->recvbuf;
1740
                                        size = recvdatabuf[i]->bufsize;
1741
                                        // call the callback
1742
                                        // printf("msgbuf %s \n",msgbuf);
1743

    
1744
                                        // nr missing fragments calculate
1745

    
1746
                                        recv_params rParams;
1747

    
1748
                                        double nrMissFrags = (double) recvdatabuf[i]->nrFragments / (double) recvdatabuf[i]->recvFragments;
1749
                                        int nrMissingFragments = (int) ceil(nrMissFrags);
1750

    
1751
                                        rParams.nrMissingFragments = nrMissingFragments;
1752
                                        rParams.nrFragments = recvdatabuf[i]->nrFragments;
1753
                                        rParams.msgtype = recvdatabuf[i]->msgtype;
1754
                                        rParams.connectionID = recvdatabuf[i]->connectionID;
1755
                                        rParams.remote_socketID = connectbuf[recvdatabuf[i]->connectionID]->external_socketID;
1756
                                        /*
1757
                                        * if(monitoringHeaderType == 1 ||
1758
                                        * monitoringHeaderType == 3){
1759
                                        * rParams->monitoring_header_data =
1760
                                        * monitoringDataHeader; }else{
1761
                                        * rParams->monitoring_header_data = NULL; } 
1762
                                        */
1763

    
1764
                                        rParams.firstPacketArrived = recvdatabuf[i]->firstPacketArrived;
1765

    
1766
                                        (receive_data_callback) (bufptr, size, msgtype, (void *) &rParams);
1767

    
1768
                                        // calback to the monitoring layer
1769
                                        mon_data_inf recv_data_inf_;
1770

    
1771
                                        recv_data_inf_.remote_socketID = connectbuf[recvdatabuf[i]->connectionID]->external_socketID;
1772
                                        recv_data_inf_.buffer = recvdatabuf[i]->recvbuf;
1773
                                        recv_data_inf_.bufSize = recvdatabuf[i]->bufsize;
1774
                                        recv_data_inf_.msgtype = recvdatabuf[i]->msgtype;
1775
                                        recv_data_inf_.monitoringHeaderType = recvdatabuf[i]->monitoringHeaderType;
1776
                                        recv_data_inf_.monitoringDataHeader = recvdatabuf[i]->monitoringDataHeader;
1777
                                        gettimeofday(&recv_data_inf_.arrival_time, NULL);
1778
                                        recv_data_inf_.firstPacketArrived =
1779
                                        recvdatabuf[i]->firstPacketArrived;
1780
                                        recv_data_inf_.nrMissingFragments = nrMissingFragments;
1781
                                        recv_data_inf_.nrFragments = recvdatabuf[i]->nrFragments;
1782
                                        recv_data_inf_.priority = false;
1783
                                        recv_data_inf_.padding = false;
1784
                                        recv_data_inf_.confirmation = false;
1785
                                        recv_data_inf_.reliable = false;
1786

    
1787
                                        (get_Recv_data_inf_cb) ((void *) &recv_data_inf_);
1788

    
1789
                                        free(recvdatabuf[i]);
1790
                                        recvdatabuf[i] = NULL;
1791
                                }
1792
                        }
1793
                }
1794
         }
1795
           }
1796

    
1797

    
1798
   // if the dataID and connectionId dont exist: create a new recv object
1799
        if (_bool == FALSE) {
1800

    
1801
                for (i = 0; i < RECVDATABUFSIZE; i++) {
1802

    
1803
                        if (recvdatabuf[i] == NULL) {
1804
                                recvdatabuf[i] = (recvdata *) malloc(sizeof(recvdata));
1805
                                recvdatabuf[i]->connectionID = local_connectionID;
1806
                                recvdatabuf[i]->seqnr = seqnr;
1807
                                recvdatabuf[i]->bufsize = size;
1808
                                recvdatabuf[i]->recvbuf = (char *) malloc(size);
1809
                                /*
1810
                                 * read the set timeout data and set it 
1811
                                 */
1812
                                recvdatabuf[i]->timeout_value.tv_sec = recv_timeout.tv_sec;
1813
                                recvdatabuf[i]->timeout_value.tv_usec = recv_timeout.tv_usec;
1814
                                recvdatabuf[i]->recvID = i;
1815
                                recvdatabuf[i]->starttime = time(NULL);
1816
                                recvdatabuf[i]->recvFragments = 1;
1817
                                recvdatabuf[i]->msgtype = msgtype;
1818
                                recvdatabuf[i]->monitoringHeaderType =        monitoringHeaderType;
1819
                                recvdatabuf[i]->firstPacketArrived = firstPacketArrived;
1820

    
1821
                                // fill the buffer with zeros
1822
                                memset(recvdatabuf[i]->recvbuf, '0', size);
1823

    
1824
                                char *bufptr = NULL;
1825
                                bufptr = recvdatabuf[i]->recvbuf;
1826
                                bufptr += offset;
1827

    
1828
                                // determine the fragmentsize
1829
                                // TODO correct this: causes segmentation faults if data is send to a not opened connection
1830
                                int fragmentsize = connectbuf[local_connectionID]->pmtusize - MSGL_HEADER_SIZE;
1831

    
1832
                                if (monitoringHeaderType == 0 || monitoringHeaderType == 1) {
1833
                                // no monitoring module header present
1834
                                        msgbufptr = &msgbuf[18];
1835
                                } else if (monitoringHeaderType == 2 || monitoringHeaderType == 3) {
1836
                                        fragmentsize = fragmentsize - MON_PACKET_HEADER_SIZE;
1837
                                        int bufpos = MON_PACKET_HEADER_SIZE + MSGL_HEADER_SIZE;
1838
                                        msgbufptr = &msgbuf[bufpos];
1839
                                        // printf("buffer %s \n ",bufptr);
1840
                                }
1841

    
1842
                                int cpysize;
1843
                                cpysize = (fragmentsize < size) ?  fragmentsize : size;
1844
                                memcpy(bufptr, msgbufptr, cpysize);
1845

    
1846

    
1847
                                double nrFrags = (double) size / (double) fragmentsize;
1848
                                int nrFragments = (int) ceil(nrFrags);
1849
                                recvdatabuf[i]->nrFragments = nrFragments;
1850

    
1851
                                /*
1852
                                * if there is only one fragment the recv is finished 
1853
                                */
1854
                                if (nrFragments == 1) {
1855
                                        recvdatabuf[i]->status = 1;
1856

    
1857
                                        // get the msgtype 
1858
                                        char msgtype = recvdatabuf[i]->msgtype;
1859

    
1860
                                        // get the right callback
1861
                                        receive_data_cb receive_data_callback = recvcbbuf[msgtype];
1862
                                        // printf("msgbuf %s \n",bufptr);
1863

    
1864
                                        // call the callback
1865
                                        recv_params rParams;
1866

    
1867
                                        double nrMissFrags =        (double) recvdatabuf[i]->nrFragments / (double) recvdatabuf[i]->recvFragments;
1868
                                        int nrMissingFragments = (int) ceil(nrMissFrags);
1869

    
1870
                                        if (monitoringHeaderType == 1 || monitoringHeaderType == 3) {
1871
                                                memcpy(monitoringDataHeader, recvdatabuf[i]->recvbuf, MON_DATA_HEADER_SIZE);
1872
                                                // shorten the recv buffer and change the
1873
                                                // buffersize 
1874
                                                recvdatabuf[i]->recvbuf += MON_DATA_HEADER_SIZE;
1875
                                                recvdatabuf[i]->bufsize -= MON_DATA_HEADER_SIZE;
1876
                                                // set this in the return parameters
1877
                                                // rParams->monitoring_header_data =
1878
                                                // monitoringDataHeader;
1879

    
1880
                                                recvdatabuf[i]->monitoringDataHeader = monitoringDataHeader;
1881
                                        } else {
1882
                                                // rParams->monitoring_header_data = NULL;
1883
                                        }
1884

    
1885
                                        rParams.nrMissingFragments = nrMissingFragments;
1886
                                        rParams.nrFragments = recvdatabuf[i]->nrFragments;
1887
                                        rParams.msgtype = recvdatabuf[i]->msgtype;
1888
                                        rParams.connectionID = recvdatabuf[i]->connectionID;
1889
                                        rParams.firstPacketArrived = 1;
1890
                                        rParams.remote_socketID = connectbuf[recvdatabuf[i]->connectionID]->external_socketID;
1891

    
1892
                                        // calback to the monitoring layer 
1893
                                        mon_data_inf recv_data_inf_;
1894

    
1895
                                        recv_data_inf_.remote_socketID = connectbuf[recvdatabuf[i]->connectionID]->external_socketID;        
1896
                                        recv_data_inf_.buffer = recvdatabuf[i]->recvbuf;
1897
                                        recv_data_inf_.bufSize = recvdatabuf[i]->bufsize;
1898
                                        recv_data_inf_.msgtype = recvdatabuf[i]->msgtype;
1899
                                        recv_data_inf_.monitoringHeaderType = recvdatabuf[i]->monitoringHeaderType;
1900
                                        recv_data_inf_.monitoringDataHeader = recvdatabuf[i]->monitoringDataHeader;
1901
                                        gettimeofday(&recv_data_inf_.arrival_time, NULL);
1902
                                        recv_data_inf_.firstPacketArrived = recvdatabuf[i]->firstPacketArrived;
1903
                                        recv_data_inf_.nrMissingFragments = nrMissingFragments;
1904
                                        recv_data_inf_.nrFragments = recvdatabuf[i]->nrFragments;
1905
                                        recv_data_inf_.priority = false;
1906
                                        recv_data_inf_.padding = false;
1907
                                        recv_data_inf_.confirmation = false;
1908
                                        recv_data_inf_.reliable = false;
1909

    
1910
                                        (get_Recv_data_inf_cb) ((void *) &recv_data_inf_);
1911

    
1912

    
1913
                                        if (recv_data_callback) {
1914
                                                (receive_data_callback) (bufptr, size, msgtype, (void *) &rParams);
1915
                                                // fill the recv_cb
1916
                                                free(recvdatabuf[i]);
1917
                                                recvdatabuf[i] = NULL;
1918
                                        }
1919
                                }
1920
                                // more then one fragment
1921
                                else {
1922

    
1923
                                        recvdatabuf[i]->status = 0;
1924

    
1925
                                        if (recv_data_callback) {
1926
                                                struct timeval timeout_value_print = { 4, 0 };
1927
                                                struct event *ev;
1928
                                                ev = evtimer_new(base, recv_timeout_cb, (void *) &recvdatabuf[i]);
1929
                                                // recvdatabuf[i]->timeout = ev;
1930
                                                event_add(ev, &recvdatabuf[i]->timeout_value);
1931
                                        }
1932
                                }
1933
                        }
1934
                        break;
1935
                }
1936
        }
1937
    // printf("still here 11\n");
1938

    
1939
    /*
1940
     * make a callback to the monitoring module after a message is recv 
1941
     */
1942
         mon_pkt_inf msginfNow;
1943
    if (monitoringHeaderType == 2 || monitoringHeaderType == 3)
1944
                msginfNow.monitoringHeader = &msgbuf[18];
1945
    else
1946
                msginfNow.monitoringHeader = NULL;
1947

    
1948
    msginfNow.monitoringHeaderType = monitoringHeaderType;
1949
    msginfNow.ttl = ttl;
1950
    msginfNow.dataID = seqnr;
1951
    msginfNow.offset = offset;
1952
    msginfNow.datasize = size;
1953
    gettimeofday(&msginfNow.arrival_time, NULL);
1954
    (get_Recv_pkt_inf_cb) ((void *) &msginfNow);
1955
}
1956

    
1957
void recv_timeout_cb(int fd, short event, void *arg)
1958
{
1959

    
1960
    // int recvID;
1961
    // memcpy(&recvID,arg,4);
1962
    printf("transmissionHandler: recv_timeout_cb is called \n ");
1963

    
1964
    if (arg != NULL) {
1965

    
1966
        recvdata *recvdataptr = (recvdata *) arg;
1967

    
1968
        if (recvdataptr->recvbuf != NULL) {
1969

    
1970
            recvdataptr->status = 1;
1971
            char monitoringHeaderType = recvdataptr->monitoringHeaderType;
1972
            char monitoringDataHeader[MON_DATA_HEADER_SIZE];
1973
            // check for the chunk header
1974

    
1975

    
1976
            if (monitoringHeaderType == 1 || monitoringHeaderType == 3) {
1977

    
1978
                memcpy(monitoringDataHeader, recvdataptr->recvbuf,
1979
                       MON_DATA_HEADER_SIZE);
1980

    
1981
                // shorten the recv buffer and change the buffersize 
1982

    
1983
                recvdataptr->recvbuf += MON_DATA_HEADER_SIZE;
1984
                recvdataptr->bufsize -= MON_DATA_HEADER_SIZE;
1985

    
1986
                recvdataptr->monitoringDataHeader = monitoringDataHeader;
1987
            }
1988
            // callback to the monitoring module
1989

    
1990
            if (recv_data_callback) {
1991

    
1992
                // get the msgtype 
1993
                char msgtype = recvdataptr->msgtype;
1994

    
1995
                // get the right callback
1996
                receive_data_cb receive_data_callback = recvcbbuf[msgtype];
1997

    
1998
                recv_params rParams;
1999
                double nrMissFrags = (double) recvdataptr->nrFragments / (double) recvdataptr->recvFragments; 
2000
                int nrMissingFragments = (int) ceil(nrMissFrags);
2001

    
2002
                rParams.nrMissingFragments = nrMissingFragments;
2003
                rParams.nrFragments = recvdataptr->nrFragments;
2004
                rParams.msgtype = recvdataptr->msgtype;
2005
                rParams.connectionID = recvdataptr->connectionID;
2006
                rParams.firstPacketArrived = recvdataptr->firstPacketArrived;
2007
                rParams.remote_socketID = connectbuf[recvdataptr->connectionID]->external_socketID;
2008

    
2009
                if (monitoringHeaderType == 1 || monitoringHeaderType == 3) {
2010

    
2011
                    // rParams->monitoring_header_data =
2012
                    // monitoringDataHeader;
2013

    
2014
                } else {
2015

    
2016
                    // rParams->monitoring_header_data = NULL;
2017

    
2018
                }
2019

    
2020

    
2021
                // call the callback 
2022
                (receive_data_callback) (recvdataptr->recvbuf, recvdataptr->bufsize, msgtype, (void *) &rParams);
2023

    
2024
                free(recvdataptr);
2025
                recvdataptr = NULL;
2026
            }
2027

    
2028

    
2029
        }
2030
    }
2031
}
2032

    
2033
void pmtu_timeout_cb(int fd, short event, void *arg)
2034
{
2035

    
2036
    printf("transmissionHandler: pmtu timeout called \n");
2037

    
2038
    int connectionID;
2039
    int msgtype;
2040
    pmtu pmtusize;
2041
    pmtu new_pmtusize;
2042
    char msgbufx[1500];
2043

    
2044
    connect_data *my_connect_data = (connect_data *) arg;
2045
    connectionID = my_connect_data->connectionID;
2046

    
2047

    
2048
    // retreive the connectionID
2049
    // memcpy(&connectionID,arg,4);
2050
    // printf("connId %d \n",connectionID);
2051
    // &connectionID = (int *)arg;
2052

    
2053
    // int *ptr = NULL;
2054
    // ptr = (int *)arg;
2055

    
2056

    
2057
    // get status and pmtu size
2058
    msgtype = connectbuf[connectionID]->status;
2059
    pmtusize = connectbuf[connectionID]->pmtutrysize;
2060

    
2061
    // printf("pmtusize: %i \n ",pmtusize);
2062

    
2063
    // decrement the pmtu size
2064
    new_pmtusize = pmtu_decrement(pmtusize);
2065

    
2066
    // printf("new_pmtusize: %i \n ",new_pmtusize);
2067

    
2068
    if (new_pmtusize == error) {
2069

    
2070
        if (connectbuf[connectionID]->internal_connect == true) {
2071

    
2072
            connectbuf[connectionID]->internal_connect = false;
2073

    
2074
            pmtu full = max;
2075

    
2076
            connectbuf[connectionID]->pmtutrysize = full;
2077
            connectbuf[connectionID]->pmtusize = full;
2078
            new_pmtusize = max;
2079
            // printf(" set pmtu size %i
2080
            // \n",connectbuf[connectionID]->pmtutrysize);
2081

    
2082
            // printf("--> connectionID: %i \n ",connectionID);
2083

    
2084
            int connID = connectionID;
2085
            create_conn_msg(msgbufx, 1500, connID, 0, &local_socketID,
2086
                            NULL, msgtype);
2087

    
2088
            connID = connectionID;
2089

    
2090
            send_conn_msg(connectionID, msgbufx, 1500);
2091

    
2092
            /*
2093
             * libevent2 
2094
             */
2095
            struct event *ev1;
2096
            ev1 =
2097
                evtimer_new(base, pmtu_timeout_cb,
2098
                            (void *) my_connect_data);
2099
            // connectbuf[connectionID]->timeout = ev;
2100
            // event_add(ev,&connectbuf[connectionID]->timeout_value);
2101
            evtimer_add(ev1, &connectbuf[connectionID]->timeout_value);
2102

    
2103

    
2104
            msgtype = 2;
2105

    
2106
        } else {
2107

    
2108
            // printf("still alive \n");
2109

    
2110
            fprintf(stderr,
2111
                    "transmissionHandler: Could not create connection with connectionID %i !\n",
2112
                    connectionID);
2113

    
2114
            (failed_Connection_cb) (connectionID, NULL);
2115
            // set the message type to a non existent message
2116
            msgtype = 2;
2117
            // delete the connection entry
2118
            free(connectbuf[connectionID]);
2119
            // envoke the callback for connection establishment
2120
        }
2121

    
2122
    }
2123

    
2124
    connectbuf[connectionID]->pmtutrysize = new_pmtusize;
2125

    
2126
    // set the buffer for the message
2127
    char msgbuf[new_pmtusize];
2128
    // struct event *ev;
2129

    
2130
    switch (msgtype) {
2131

    
2132
    case 0:
2133

    
2134
        // create and send a connection message
2135
        create_conn_msg(msgbuf, new_pmtusize, connectionID, 0,
2136
                        &local_socketID, NULL, msgtype);
2137

    
2138
        send_conn_msg(connectionID, msgbuf, new_pmtusize);
2139

    
2140
        // set a timeout event for the pmtu discovery 
2141
        // timeout_set(connectbuf[connectionID]->timeout,pmtu_timeout_cb,(void 
2142
        // *)&connectionID);
2143

    
2144
        // timeout_add(connectbuf[connectionID]->timeout,&connectbuf[connectionID]->timeout_value);
2145

    
2146
        printf("transmissionHandler: connId %d \n", connectionID);
2147

    
2148

    
2149
        /*
2150
         * libevent2 
2151
         */
2152
        struct event *ev1;
2153
        ev1 = evtimer_new(base, pmtu_timeout_cb, (void *) my_connect_data);
2154
        // connectbuf[connectionID]->timeout = ev;
2155
        // event_add(ev,&connectbuf[connectionID]->timeout_value);
2156
        evtimer_add(ev1, &connectbuf[connectionID]->timeout_value);
2157

    
2158
        break;
2159

    
2160
    case 1:
2161

    
2162
        // create and send a connection message
2163
        create_conn_msg(msgbuf, new_pmtusize,
2164
                        connectbuf[connectionID]->connectionID,
2165
                        connectbuf[connectionID]->external_connectionID,
2166
                        NULL, NULL, msgtype);
2167

    
2168
        send_conn_msg(connectionID, msgbuf, new_pmtusize);
2169

    
2170
        // set a timeout event for the pmtu discovery 
2171
        // timeout_set(connectbuf[connectionID]->timeout,pmtu_timeout_cb,(void 
2172
        // *)&connectionID);
2173
        // timeout_add(connectbuf[connectionID]->timeout,&connectbuf[connectionID]->timeout_value);
2174

    
2175
        /*
2176
         * libevent2 
2177
         */
2178
        struct event *ev2;
2179
        ev2 = evtimer_new(base, pmtu_timeout_cb, (void *) my_connect_data);
2180
        // connectbuf[connectionID]->timeout = ev;
2181
        event_add(ev2, &connectbuf[connectionID]->timeout_value);
2182

    
2183
        break;
2184

    
2185
    }
2186

    
2187
}
2188

    
2189
/*
2190
 * decrements the mtu size
2191
 */
2192
pmtu pmtu_decrement(pmtu pmtusize)
2193
{
2194

    
2195
    pmtu pmtu_return_size;
2196

    
2197
    if (pmtusize == max) {
2198

    
2199
        pmtu_return_size = dsl;
2200

    
2201
    } else if (pmtusize == dsl) {
2202

    
2203
        // printf("set pmtu dsl \n");
2204
        pmtu_return_size = dslmedium;
2205

    
2206
    } else if (pmtusize == dslmedium) {
2207

    
2208
        pmtu_return_size = dslslim;
2209

    
2210
    } else if (pmtusize == dslslim) {
2211

    
2212
        pmtu_return_size = belowdsl;
2213

    
2214
    } else if (pmtusize == belowdsl) {
2215

    
2216
        pmtu_return_size = min;
2217

    
2218
    } else {
2219
        printf("transmissionHandler: only unrealted error \n ");
2220
        pmtu_return_size = error;
2221

    
2222
    }
2223

    
2224
    return pmtu_return_size;
2225

    
2226
}
2227

    
2228
void pmtu_error_cb_th(char *msg, int msglen)
2229
{
2230

    
2231
    printf("pmtu error callback \n ");
2232

    
2233
    printf("+pmtu size %d \n", msglen);
2234

    
2235
    char *msgbufptr = NULL;
2236
    int msgtype;
2237
    int connectionID;
2238
    pmtu pmtusize;
2239
    pmtu new_pmtusize;
2240
    int dead = 0;
2241

    
2242
    // check the packettype
2243
    msgbufptr = &msg[0];
2244

    
2245
    // check the msgtype
2246
    msgbufptr = &msg[1];
2247
    memcpy(&msgtype, msgbufptr, 4);
2248

    
2249
    if (msgtype == 0) {
2250

    
2251
        // get the connectionID
2252
        msgbufptr = &msg[5];
2253
        memcpy(&connectionID, msgbufptr, 4);
2254

    
2255
        int msgtype_c = connectbuf[connectionID]->status;
2256
        pmtusize = connectbuf[connectionID]->pmtutrysize;
2257

    
2258
        if (msgtype_c != msgtype) {
2259
            dead = 1;
2260
        }
2261

    
2262

    
2263
    } else if (msgtype == 1) {
2264

    
2265
        // read the connectionID
2266
        msgbufptr = &msg[9];
2267
        memcpy(&connectionID, msgbufptr, 4);
2268

    
2269
        int msgtype_c = connectbuf[connectionID]->status;
2270
        pmtusize = connectbuf[connectionID]->pmtutrysize;
2271

    
2272
        if (msgtype_c != msgtype) {
2273
            dead = 1;
2274
        }
2275

    
2276
    }
2277
    // decrement the pmtu size 
2278
    new_pmtusize = pmtu_decrement(pmtusize);
2279

    
2280
    connectbuf[connectionID]->pmtutrysize = new_pmtusize;
2281

    
2282
    if (new_pmtusize == error) {
2283

    
2284

    
2285
        fprintf(stderr,
2286
                "transmissionHandler:  Could not create connection with connectionID %i !\n",
2287
                connectionID);
2288

    
2289
        (failed_Connection_cb) (connectionID, NULL);
2290
        // set the message type to a non existent message 
2291
        msgtype = 2;
2292
        // delete the connection entry 
2293
        free(connectbuf[connectionID]);
2294

    
2295
    }
2296

    
2297
    if (msgtype == 0 && dead != 1) {
2298

    
2299
        // stop the timeout event
2300
        // timeout_del(connectbuf[connectionID]->timeout);
2301
        /*
2302
         * libevent2 
2303
         */
2304

    
2305
        // event_del(connectbuf[connectionID]->timeout);
2306

    
2307
        // set the buffer for the message
2308
        char msgbuf[new_pmtusize];
2309

    
2310
        // create and send a connection message
2311
        create_conn_msg(msgbuf, new_pmtusize, connectionID, 0,
2312
                        &local_socketID, NULL, 0);
2313

    
2314
        send_conn_msg(connectionID, msgbuf, new_pmtusize);
2315

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

    
2320
        // timeout_add(connectbuf[connectionID]->timeout,&connectbuf[connectionID]->timeout_value);
2321

    
2322
        /*
2323
         * libevent2 
2324
         */
2325

    
2326
        struct event *ev;
2327
        ev = evtimer_new(base, pmtu_timeout_cb,
2328
                         (void *) connectbuf[connectionID]);
2329

    
2330
        // connectbuf[connectionID]->timeout = ev;
2331

    
2332
        event_add(ev, &connectbuf[connectionID]->timeout_value);
2333

    
2334
    } else if (msgtype == 1 && dead != 1) {
2335

    
2336
        // stop the timeout event
2337
        // timeout_del(connectbuf[connectionID]->timeout);
2338

    
2339
        /*
2340
         * libevent2 
2341
         */
2342
        // printf("still here 11 \n");
2343
        // printf("ev %d \n",connectbuf[connectionID]->timeout);
2344
        // event_del(connectbuf[connectionID]->timeout );
2345
        // evtimer_del(connectbuf[connectionID]->timeout );
2346

    
2347
        char msgbufn[new_pmtusize];
2348

    
2349
        // create and send a connection message
2350
        create_conn_msg(msgbufn, new_pmtusize,
2351
                        connectbuf[connectionID]->connectionID,
2352
                        connectbuf[connectionID]->external_connectionID,
2353
                        NULL, NULL, 1);
2354

    
2355
        send_conn_msg(connectionID, msgbufn, new_pmtusize);
2356

    
2357
        // set a timeout event for the pmtu discovery 
2358
        // timeout_set(connectbuf[connectionID]->timeout,pmtu_timeout_cb,(void 
2359
        // *)&connectionID);
2360
        // timeout_add(connectbuf[connectionID]->timeout,&connectbuf[connectionID]->timeout_value);
2361

    
2362
        /*
2363
         * libevent2 
2364
         */
2365
        // struct event *ev;
2366
        // ev = evtimer_new(base,pmtu_timeout_cb, (void
2367
        // *)connectbuf[connectionID]);
2368
        // connectbuf[connectionID]->timeout = ev;
2369
        // event_add(ev,&connectbuf[connectionID]->timeout_value);
2370

    
2371
    }
2372

    
2373

    
2374
}
2375

    
2376
/*
2377
 * compare the external IP address of two socketIDs 
2378
 */
2379
int
2380
compare_external_address_socketIDs(socketID_handle sock1,
2381
                                   socketID_handle sock2)
2382
{
2383

    
2384
    int resultValue = 0;
2385
    socketaddrgen udpgen1;
2386
    socketaddrgen udpgen2;
2387
    struct sockaddr_in udpaddr1;
2388
    struct sockaddr_in udpaddr2;
2389

    
2390
    /*
2391
     * compare internal addr 
2392
     */
2393
    udpgen1 = sock1->internal_addr;
2394
    udpgen2 = sock2->internal_addr;
2395

    
2396
    udpaddr1 = udpgen1.udpaddr;
2397
    udpaddr2 = udpgen2.udpaddr;
2398

    
2399
    if (udpaddr1.sin_addr.s_addr != udpaddr2.sin_addr.s_addr) {
2400

    
2401
        resultValue = 1;
2402

    
2403
    }
2404

    
2405
    return resultValue;
2406

    
2407
}
2408

    
2409
/*
2410
 * compares 2 socketIDs: returns 0 if they are equl otherwise 1 
2411
 */
2412
int compare_socketIDs(socketID_handle sock1, socketID_handle sock2)
2413
{
2414

    
2415
    int resultValue = 0;
2416
    socketaddrgen udpgen1;
2417
    socketaddrgen udpgen2;
2418
    struct sockaddr_in udpaddr1;
2419
    struct sockaddr_in udpaddr2;
2420

    
2421
    /*
2422
     * compare internal addr 
2423
     */
2424
    udpgen1 = sock1->internal_addr;
2425
    udpgen2 = sock2->internal_addr;
2426

    
2427
    udpaddr1 = udpgen1.udpaddr;
2428
    udpaddr2 = udpgen2.udpaddr;
2429

    
2430
    if (udpaddr1.sin_addr.s_addr != udpaddr2.sin_addr.s_addr) {
2431

    
2432
        resultValue = 1;
2433

    
2434
    }
2435

    
2436
    if (udpaddr1.sin_port != udpaddr2.sin_port) {
2437

    
2438
        resultValue = 1;
2439

    
2440
    }
2441

    
2442
    /*
2443
     * compare external addr 
2444
     */
2445
    udpgen1 = sock1->external_addr;
2446
    udpgen2 = sock2->external_addr;
2447
    udpaddr1 = udpgen1.udpaddr;
2448
    udpaddr2 = udpgen2.udpaddr;
2449

    
2450
    if (udpaddr1.sin_addr.s_addr != udpaddr2.sin_addr.s_addr) {
2451

    
2452
        resultValue = 1;
2453

    
2454
    }
2455

    
2456
    if (udpaddr1.sin_port != udpaddr2.sin_port) {
2457

    
2458
        resultValue = 1;
2459

    
2460
    }
2461

    
2462

    
2463
    return resultValue;
2464

    
2465
}
2466

    
2467
/*
2468
 * the timeout of the NAT traversal 
2469
 */
2470
void nat_traversal_timeout(int fd, short event, void *arg)
2471
{
2472

    
2473
    // socketID_handle socketID = (void *)arg;
2474

    
2475
    if (NAT_traversal == false) {
2476

    
2477
        printf("transmissionHandler: NAT traversal resend \n ");
2478
        send_stun_request(socketfd, &stun_server);
2479

    
2480
        /*
2481
         * enter a NAT traversal timeout that takes care of retransmission 
2482
         */
2483
        struct event *ev1;
2484
        struct timeval timeout_value_NAT_traversal = { 1, 0 };
2485
        ev1 = evtimer_new(base, nat_traversal_timeout, NULL);
2486
        event_add(ev1, &timeout_value_NAT_traversal);
2487
        // callback to the upper layer indicating that NAT traversal
2488
        // failed
2489
        (receive_SocketID_cb) (&local_socketID, 2);
2490

    
2491
    }
2492

    
2493
}
2494

    
2495
int get_standard_ttl(socketID_handle socketID, int *ttl)
2496
{
2497

    
2498
    evutil_socket_t socket = socketfd;
2499
    int returnValue = 0;
2500

    
2501
    returnValue = getTTL(socket, ttl);
2502

    
2503
    return returnValue;
2504
}
2505

    
2506
socketID_handle get_local_socketID(int *errorstatus)
2507
{
2508

    
2509
    if (NAT_traversal == false) {
2510

    
2511
        *errorstatus = 2;
2512

    
2513
    } else {
2514

    
2515
        *errorstatus = 0;
2516

    
2517
    }
2518

    
2519
    return &local_socketID;
2520

    
2521
}
2522

    
2523

    
2524
int get_external_IP(char *external_addr)
2525
{
2526

    
2527
    socketaddrgen udpgen;
2528
    struct sockaddr_in udpaddr;
2529

    
2530
    udpgen = local_socketID.external_addr;
2531
    udpaddr = udpgen.udpaddr;
2532

    
2533
    inet_ntop(AF_INET, &(udpaddr.sin_addr), external_addr,
2534
              INET_ADDRSTRLEN);
2535

    
2536
    if (external_addr == NULL) {
2537

    
2538
        return -1;
2539

    
2540
    } else {
2541

    
2542
        return 0;
2543

    
2544
    }
2545

    
2546
}
2547

    
2548

    
2549
int socketID_to_String(socketID_handle socketID, char *socketID_string)
2550
{
2551

    
2552
    socketaddrgen udpgen;
2553
    struct sockaddr_in udpaddr;
2554
    char external_addr[INET_ADDRSTRLEN];
2555
    udpgen = socketID->external_addr;
2556
    udpaddr = udpgen.udpaddr;
2557
    // save external port
2558
    int external_port = udpaddr.sin_port;
2559
    // convert external IP address from binary to string
2560
    inet_ntop(AF_INET, &(udpaddr.sin_addr), external_addr,
2561
              INET_ADDRSTRLEN);
2562

    
2563
    char internal_addr[INET_ADDRSTRLEN];
2564
    udpgen = socketID->internal_addr;
2565
    udpaddr = udpgen.udpaddr;
2566
    // save external port
2567
    int internal_port = udpaddr.sin_port;
2568
    // convert internal IP address from binary to string
2569
    inet_ntop(AF_INET, &(udpaddr.sin_addr), internal_addr,
2570
              INET_ADDRSTRLEN);
2571

    
2572
    if (external_addr == NULL || internal_addr == NULL) {
2573

    
2574
        return -1;
2575

    
2576
    } else {
2577

    
2578
        char *bufptr;
2579
        bufptr = &socketID_string[0];
2580

    
2581
        memcpy(bufptr, external_addr, INET_ADDRSTRLEN);
2582

    
2583
        bufptr = &socketID_string[16];
2584

    
2585
        memcpy(bufptr, &external_port, 4);
2586

    
2587
        bufptr = &socketID_string[20];
2588

    
2589
        memcpy(bufptr, internal_addr, INET_ADDRSTRLEN);
2590

    
2591
        bufptr = &socketID_string[36];
2592

    
2593
        memcpy(bufptr, &internal_port, 4);
2594

    
2595
        return 0;
2596

    
2597
    }
2598

    
2599
}
2600

    
2601
socketID_handle string_to_socketID(char *socketID_string)
2602
{
2603

    
2604
    char external_addr[INET_ADDRSTRLEN];
2605
    int external_port;
2606
    char internal_addr[INET_ADDRSTRLEN];
2607
    int internal_port;
2608

    
2609
    // get the data into variables
2610
    char *bufptr;
2611
    bufptr = &socketID_string[0];
2612
    memcpy(external_addr, bufptr, INET_ADDRSTRLEN);
2613

    
2614
    bufptr = &socketID_string[16];
2615
    memcpy(&external_port, bufptr, 4);
2616

    
2617
    bufptr = &socketID_string[20];
2618
    memcpy(internal_addr, bufptr, INET_ADDRSTRLEN);
2619

    
2620
    bufptr = &socketID_string[36];
2621
    memcpy(&internal_port, bufptr, 4);
2622

    
2623

    
2624
    struct sockaddr_in udpaddr_ex;
2625
    udpaddr_ex.sin_family = AF_INET;
2626
    udpaddr_ex.sin_addr.s_addr = inet_addr(external_addr);
2627
    udpaddr_ex.sin_port = external_port;
2628

    
2629
    struct sockaddr_in udpaddr_in;
2630
    udpaddr_in.sin_family = AF_INET;
2631
    udpaddr_in.sin_addr.s_addr = inet_addr(internal_addr);
2632
    udpaddr_in.sin_port = internal_port;
2633

    
2634
    socketaddrgen udpgen_ex;
2635
    udpgen_ex.udpaddr = udpaddr_ex;
2636
    local_socketID.external_addr = udpgen_ex;
2637

    
2638
    socketaddrgen udpgen_in;
2639
    udpgen_in.udpaddr = udpaddr_in;
2640
    local_socketID.external_addr = udpgen_in;
2641

    
2642
    socketID_handle new_SocketID = malloc(sizeof(socket_ID));
2643
    new_SocketID->external_addr = udpgen_ex;
2644
    new_SocketID->internal_addr = udpgen_in;
2645

    
2646
    // return the socketID_handle
2647
    return new_SocketID;
2648
}
2649

    
2650

    
2651
int get_connection_status(int connectionID)
2652
{
2653

    
2654
    // get the connection status
2655
    int stat = 0;
2656
    stat = connectbuf[connectionID]->status;
2657
    // translate the status
2658
    int returnvalue = 0;
2659

    
2660
    if (stat != 2) {
2661

    
2662
        returnvalue = -1;
2663

    
2664
    }
2665

    
2666
    return returnvalue;
2667

    
2668
}
2669

    
2670

    
2671
int connection_exist(socketID_handle socketID)
2672
{
2673

    
2674

    
2675
    int i = 0;
2676

    
2677
    /*
2678
     * check if another connection for the external connectionID exist
2679
     * that was established \ within the last 2 seconds 
2680
     */
2681
    for (i = 0; i < CONNECTBUFSIZE; i++) {
2682

    
2683
        if (connectbuf[i] != NULL) {
2684

    
2685
            if (compare_socketIDs
2686
                (connectbuf[i]->external_socketID, socketID)
2687
                == 0) {
2688

    
2689
                return i;
2690

    
2691
            }
2692

    
2693
        }
2694
    }
2695

    
2696
    return -1;
2697
}
2698

    
2699
unsigned long resolve(const char *ipaddr)
2700
{
2701
    struct hostent *h = gethostbyname(ipaddr);
2702
    if (!h) {
2703
        fprintf(stderr, "Unable to resolve hostname %s\n", ipaddr);
2704
        exit(-1);
2705
    }
2706
    unsigned long *addr = (unsigned long *) (h->h_addr);
2707
    return *addr;
2708
}