Statistics
| Branch: | Revision:

ml / transmissionHandler.c @ 8b17961c

History | View | Annotate | Download (66.7 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 <string.h>
44
#include <sys/types.h>
45
#include <arpa/inet.h>
46
#include <errno.h>
47
#include <time.h>
48
#include <math.h>
49
#include "util/udpSocket.h"
50
#include "util/stun.h"
51
#include "stdint.h"
52
#include "transmissionHandler.h"
53

    
54
/* a pointer to a libevent instance */
55
struct event_base *base;
56

    
57
/* define the nr of connections the messaging layer can handle */
58
#define CONNECTBUFSIZE 10000
59
/* define the nr of data that can be received parallel */
60
#define RECVDATABUFSIZE 10000
61
/* define an array for message multiplexing */
62
#define MSGMULTIPLEXSIZE 127
63

    
64
/* global variables */
65
/* define a buffer of pointers to connect structures */
66
connect_data *connectbuf[CONNECTBUFSIZE];
67

    
68
/* define a pointer buffer with pointers to recv_data structures */
69
recvdata *recvdatabuf[RECVDATABUFSIZE];
70

    
71
/* define a pointer buffer for message multiplexing */
72
receive_data_cb recvcbbuf[MSGMULTIPLEXSIZE];
73

    
74
/* stun server address  */
75
struct sockaddr_in stun_server;
76

    
77
/* receive timeout  */
78
struct timeval recv_timeout;
79

    
80
/* boolean NAT traversal successful if true  */
81
boolean NAT_traversal; 
82

    
83
/* file descriptor for local socket */
84
evutil_socket_t socketfd;
85

    
86
/* local socketID  */
87
socket_ID local_socketID;
88

    
89
socketID_handle loc_socketID = &local_socketID;
90

    
91
/* callback function pointers  */
92
/* monitoring module callbacks */
93
get_recv_pkt_inf_cb get_Recv_pkt_inf_cb;
94
set_monitoring_header_pkt_cb set_Monitoring_header_pkt_cb;
95
get_recv_data_inf_cb get_Recv_data_inf_cb;
96
get_send_data_inf_cb get_Send_data_inf_cb;
97
set_monitoring_header_data_cb set_Monitoring_header_data_cb;
98
/* connection callbacks  */
99
receive_connection_cb receive_Connection_cb;
100
connection_failed_cb failed_Connection_cb;
101
/* local socketID callback  */
102
receive_localsocketID_cb receive_SocketID_cb; 
103

    
104
/* boolean that defines if received data is transmitted to the upper layer via callback or via upper layer polling  */
105
boolean recv_data_callback;
106

    
107
/* functions  */
108
/* register callback functions */
109

    
110
void register_get_recv_pkt_inf(get_recv_pkt_inf_cb recv_pkt_inf_cb){
111

    
112
  if(recv_pkt_inf_cb == NULL){
113

    
114
    printf("Register get_recv_pkt_inf_cb failed: NULL ptr  \n");
115

    
116
  }else{
117

    
118
  get_Recv_pkt_inf_cb = recv_pkt_inf_cb;
119

    
120
  }
121
}
122

    
123
void register_set_monitoring_header_pkt_cb(set_monitoring_header_pkt_cb monitoring_header_pkt_cb){
124

    
125
  if(monitoring_header_pkt_cb == NULL){
126

    
127
    printf("Register set_monitoring_header_pkt_cb: NULL ptr  \n");
128

    
129
  }else{
130

    
131
  set_Monitoring_header_pkt_cb = monitoring_header_pkt_cb;
132

    
133
  }
134
}
135

    
136
void register_get_recv_data_inf(get_recv_data_inf_cb recv_data_inf_cb){
137

    
138
  if(recv_data_inf_cb == NULL){
139

    
140
    printf("Register get_recv_data_inf_cb: NULL ptr  \n");
141

    
142
  }else{
143

    
144
  get_Recv_data_inf_cb = recv_data_inf_cb ;
145
  
146
  }
147
}
148

    
149
void register_get_send_data_inf(get_send_data_inf_cb  send_data_inf_cb){
150

    
151
  if(send_data_inf_cb == NULL){
152

    
153
    printf("Register get_send_data_inf_cb: NULL ptr  \n");
154

    
155
  }else{
156

    
157
  get_Send_data_inf_cb = send_data_inf_cb ;
158

    
159
  }
160
}
161

    
162
void register_set_monitoring_header_data_cb(set_monitoring_header_data_cb monitoring_header_data_cb){
163

    
164
  if(monitoring_header_data_cb  == NULL){
165

    
166
    printf("Register set_monitoring_header_data_cb : NULL ptr  \n");
167

    
168
  }else{
169

    
170
  set_Monitoring_header_data_cb =  monitoring_header_data_cb ;
171

    
172
  }
173

    
174
}
175

    
176
void register_recv_connection_cb(receive_connection_cb connection_cb){
177

    
178
  if(connection_cb == NULL){
179

    
180
    printf("Register receive_connection_cb: NULL ptr  \n");
181

    
182
  }else{
183

    
184
  receive_Connection_cb  = connection_cb ;
185

    
186
  }
187
}
188

    
189
void register_recv_localsocketID_cb(receive_localsocketID_cb local_socketID_cb){
190

    
191
  if(local_socketID_cb == NULL){
192

    
193
    printf("Register receive_localsocketID_cb: NULL ptr \n");
194

    
195
  }else{
196

    
197
    receive_SocketID_cb  = local_socketID_cb ;
198

    
199
  }
200

    
201

    
202

    
203
}
204

    
205

    
206
void register_error_connection_cb(connection_failed_cb connection_fail){
207

    
208
  if(connection_fail  == NULL){
209

    
210
    printf("Register connection_failed_cb: NULL ptr  \n");
211

    
212
  }else{
213

    
214
  failed_Connection_cb = connection_fail;
215

    
216
  }
217

    
218
}
219

    
220

    
221
void register_recv_data_cb(receive_data_cb data_cb,unsigned char msgtype){
222
  
223
  if(msgtype > 126){
224

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

    
227
  }
228

    
229
  if(data_cb == NULL){
230

    
231
    printf("Register receive data callback: NUll ptr \n ");
232

    
233
  }else{
234

    
235
  recvcbbuf[msgtype] = data_cb;
236
  
237
  }
238
}
239

    
240
void init_transmissionHandler(boolean recv_data_cb,struct timeval timeout_value,const int port, const char *ipaddr,const int stun_port,const char *stun_ipaddr,receive_localsocketID_cb local_socketID_cb,void *arg){
241

    
242
  recv_data_callback = recv_data_cb;
243
  setRecvTimeout(timeout_value);
244
  setStunServer(stun_port,stun_ipaddr);
245
  register_recv_localsocketID_cb(local_socketID_cb); 
246
  create_socket(port,ipaddr);
247
  base = (struct event_base *)arg;
248
}
249

    
250
/* Sockets */
251
/* returns a handle to the socketID struct
252
 * the ipaddr can be a null pointer. Then all available ipaddr on the machine are choosen.*/
253
void create_socket(const int port, const char *ipaddr) {
254

    
255
  //int udpSocket = 0;
256
  /*libevent2*/
257
  int i;
258
  
259
  struct sockaddr_in udpaddr;                                                
260
  udpaddr.sin_family = AF_INET;                                              
261
  if (ipaddr == NULL){                                                       
262
    udpaddr.sin_addr.s_addr = htonl(INADDR_ANY);                               
263
  }else{                                                                     
264
    udpaddr.sin_addr.s_addr = htonl(inet_addr(ipaddr));                      
265
  }                                                                          
266
  udpaddr.sin_port = htons(port);                                            
267
  socketaddrgen udpgen;                                                
268
  udpgen.udpaddr = udpaddr;    
269
  local_socketID.internal_addr = udpgen;
270

    
271
  socketfd = createSocket(port,ipaddr);
272

    
273
  struct event *ev;
274
  ev = event_new(base,socketfd,EV_READ|EV_PERSIST,recv_pkg,NULL);
275

    
276
  event_add(ev,NULL);
277

    
278
  /* send the NAT traversal STUN request */
279
  send_stun_request(socketfd,&stun_server);
280

    
281
  /* enter a NAT traversal timeout that takes care of retransmission  */
282
  struct event *ev1;
283
  struct timeval timeout_value_NAT_traversal = {2,0};  
284
  ev1 = evtimer_new(base,nat_traversal_timeout,NULL);
285
  event_add(ev1,&timeout_value_NAT_traversal);
286

    
287
  NAT_traversal = false;
288
  
289
}
290

    
291
void close_socket(socketID_handle socketID){
292

    
293
   free(socketID);
294

    
295
}
296

    
297
/* Connections */
298
//the first socketID is the from socketID, the second one is the to socketID
299

    
300
int open_connection(socketID_handle external_socketID,int *connectionID,receive_connection_cb connection_cb,void *arg){
301

    
302
  if(external_socketID == NULL){
303

    
304
    printf("cannot open connection: one of the socketIDs is NULL \n"); 
305
    return 0;
306

    
307
  }else 
308
    if (NAT_traversal == false){
309

    
310
      printf("cannot open connection: NAT traversal for socketID still in progress  \n");
311
      return 0;
312

    
313
    }else if(connection_cb == NULL){
314

    
315
      printf("cannot open connection: connection_cb is NULL \n");
316
      return 0;
317

    
318
    }else{
319
                                                            
320
  //include pmtu discovery
321
  pmtu pmtu_size = max;
322
  msgtypes msgtype = invite;
323
  char msgbuf[max];
324
  int i = 0; 
325
  int seqnr = 0;
326
  boolean setEntry = false;
327

    
328
  //check if that connection already exist
329
  int exist = connection_exist(external_socketID);
330

    
331
  //if so check if it is ready to use
332
  if(exist != -1){
333

    
334
    int ready = get_connection_status(exist);  
335

    
336
    //if so use the callback immidiatley
337
    if(ready == 0){
338
      
339
      (connection_cb)(exist,arg);
340

    
341
    }
342
    //otherwise just write the connection cb and the arg pointer into the connection struct
343
    else{
344

    
345
      connectbuf[i]->connection_cb_2 = connection_cb;
346
      connectbuf[i]->arg_2 = arg;
347

    
348
    }
349

    
350
  }else{
351
  //make entry in connection_establishment array
352
  for(i = 0;i < CONNECTBUFSIZE;i++){
353

    
354
    
355
    boolean internal_connect_ = false;    
356

    
357

    
358
    int check_ext_addr = compare_external_address_socketIDs(external_socketID,&local_socketID);
359

    
360
    if (check_ext_addr == 0){
361

    
362
      internal_connect_ = true;
363

    
364
    }
365

    
366
    if (connectbuf[i] == NULL){
367
      
368
      connectbuf[i] = (connect_data *)malloc(sizeof(connect_data));
369
      connectbuf[i]->starttime = time(NULL);
370
      connectbuf[i]->external_socketID = external_socketID;
371
      connectbuf[i]->pmtutrysize = pmtu_size;
372
      connectbuf[i]->pmtusize = pmtu_size;
373
      connectbuf[i]->status = msgtype;
374
      connectbuf[i]->seqnr = seqnr;
375
      connectbuf[i]->internal_connect = internal_connect_;
376
      /* timeout values for the pmtu discovery */
377
      connectbuf[i]->timeout_value.tv_sec = 15;
378
      connectbuf[i]->timeout_value.tv_usec = 0;
379
      connectbuf[i]->connectionID = i;
380
      connectbuf[i]->connection_cb_1 = connection_cb;
381
      connectbuf[i]->arg_1 = arg;
382
      *connectionID = i;
383
      setEntry = true;
384
      break;
385
      }
386

    
387
    }
388
  }
389
  if (setEntry == false){
390

    
391
    printf("transmissionHandler:  Could not open connection: Connbuffer full \n ");
392

    
393
  }
394

    
395
  //create and send a connection message
396
  create_conn_msg(msgbuf,pmtu_size,*connectionID,0,&local_socketID,external_socketID,msgtype);
397

    
398
  send_conn_msg(*connectionID,msgbuf,pmtu_size);  
399

    
400
  struct event *ev;
401
  ev = evtimer_new(base,pmtu_timeout_cb, (void *)connectbuf[i]);
402
  event_add(ev,&connectbuf[*connectionID]->timeout_value);
403

    
404
  return 1;
405
  }
406
}
407

    
408
void close_connection(const int connectionID){
409

    
410
  //remove it from the connection array
411
  free(connectbuf[connectionID]);
412

    
413
}
414

    
415
void keep_connection_alive(const int connectionID){
416

    
417
  //to be done with the NAT traversal
418
  //send a message over the wire
419
  printf("\n");
420

    
421
}
422

    
423
int send_all_data(const int connectionID,send_all_data_container *container,int nr_entries,unsigned char msgtype,send_params *sParams){
424

    
425
  
426

    
427
  if (nr_entries < 1 || nr_entries > 5 ){
428

    
429
    printf("send_all_data error: nr_enties is not between 1 and 5 \n ");
430
    return 0; 
431

    
432
  }else{
433

    
434
    if (nr_entries == 1){
435

    
436
      send_data(connectionID, container->buffer_1,container->length_1,msgtype,sParams); 
437
 
438
      return 1; 
439

    
440
    }else if(nr_entries == 2){
441

    
442
      int buflen = container->length_1 + container->length_2;
443
      char buf[buflen];
444
      memcpy(buf,container->buffer_1,container->length_1);
445
      memcpy(&buf[container->length_1],container->buffer_2,container->length_2);
446
      send_data(connectionID,buf,buflen,msgtype,sParams);
447

    
448
      return 1;
449

    
450
    }else if(nr_entries == 3){
451

    
452
      int buflen = container->length_1 + container->length_2 + container->length_3;
453
      char buf[buflen];
454
      memcpy(buf,container->buffer_1,container->length_1);
455
      memcpy(&buf[container->length_1],container->buffer_2,container->length_2);
456
      memcpy(&buf[container->length_2],container->buffer_3,container->length_3);
457
      send_data(connectionID,buf,buflen,msgtype,sParams);
458

    
459

    
460
      return 1;
461

    
462
    }else if(nr_entries == 4){
463

    
464
      int buflen = container->length_1 + container->length_2 + container->length_3 + container->length_4;
465
      char buf[buflen];
466
      memcpy(buf,container->buffer_1,container->length_1);
467
      memcpy(&buf[container->length_1],container->buffer_2,container->length_2);
468
      memcpy(&buf[container->length_2],container->buffer_3,container->length_3);
469
      memcpy(&buf[container->length_3],container->buffer_4,container->length_4);
470
      send_data(connectionID,buf,buflen,msgtype,sParams);
471

    
472
      return 1;
473

    
474
    }else{
475

    
476
      int buflen = container->length_1 + container->length_2 + container->length_3 + container->length_4 + container->length_5;
477
      char buf[buflen];
478
      memcpy(buf,container->buffer_1,container->length_1);
479
      memcpy(&buf[container->length_1],container->buffer_2,container->length_2);
480
      memcpy(&buf[container->length_2],container->buffer_3,container->length_3);
481
      memcpy(&buf[container->length_3],container->buffer_4,container->length_4);
482
      memcpy(&buf[container->length_4],container->buffer_5,container->length_5);
483
      send_data(connectionID,buf,buflen,msgtype,sParams);
484

    
485
      return 1;
486
    }
487

    
488
  }
489

    
490

    
491
}
492

    
493
/* send an entire block of data  */
494
void send_data(const int connectionID,char *sendbuf,int bufsize,unsigned char msgtype ,send_params *sParams){
495

    
496
  if(sParams == NULL){
497

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

    
500
  }else{
501

    
502
  //set the messagetype
503
  char packettype = msgtype;
504

    
505
  //get these variables from the connection
506
  socketID_handle local_socketID;
507
  socketID_handle external_socketID;
508
  int udpSocket;
509
  pmtu frag_size; 
510
  int sendCounter = 0;
511
  //create some data for the monitoring header
512
  //The messaging layer header requires 13 bytes
513
  unsigned int dataID = 0;
514
  unsigned int offset = 0;
515
  unsigned int datasize = 0;
516
  /*
517
   * The monitoring header type has a range from 0 to 3
518
   * The numbers determine if a monitoring packet hader / monitoring data header is present
519
   *                                                                                   
520
   *     monitoring header type | data header | pkt header                                  
521
   *     -------------------------------------------------                        
522
   *               0            |     No      |    No                                
523
   *               1            |     Yes     |    No                               
524
   *               2            |     No      |    Yes                           
525
   *               3            |     Yes     |    Yes         
526
   */
527
  char monitoringHeaderType = 0;  
528
  char monitoringPktHeader[MON_PACKET_HEADER_SIZE];
529
  char monitoringDataHeader[MON_DATA_HEADER_SIZE];
530
  int monitoring_data_header_set = 0;
531
  int monitoring_pkt_header_set = 0;
532
  int size_sendbuf_monitoring_header = bufsize + MON_DATA_HEADER_SIZE;
533
  char sendbuf_monitoring_header[size_sendbuf_monitoring_header];
534

    
535
  //a callback to the monitoring module if a data header should be set
536
  send_pkt_type_and_dst_inf s_pkt_inf;
537

    
538
  s_pkt_inf.remote_socketID = connectbuf[connectionID]->external_socketID ;
539
  s_pkt_inf.msgtype = msgtype;
540

    
541
  monitoring_data_header_set = (set_Monitoring_header_data_cb)(monitoringDataHeader,&s_pkt_inf);
542

    
543
  //set the monitoringHeaderType accordingly
544
  if (monitoring_data_header_set == 1){
545

    
546
    monitoringHeaderType = 1;
547

    
548
    //increase the size of the buffer
549
    printf("transmissionHandler: set the monitoring module data header \n  ");
550
    char bufcpy[bufsize];
551
    memcpy(bufcpy,sendbuf,bufsize);
552
    printf("bufsize old: %d \n ",bufsize);
553
    memcpy(sendbuf_monitoring_header,monitoringDataHeader,MON_DATA_HEADER_SIZE);
554
    memcpy(&sendbuf_monitoring_header[MON_DATA_HEADER_SIZE],sendbuf,bufsize);
555
    
556
    bufsize += MON_DATA_HEADER_SIZE;
557
    sendbuf = sendbuf_monitoring_header;
558
    printf("transmissionHandler: set the monitoring module data header \n bufsize %d \n",bufsize );
559

    
560
  }
561

    
562

    
563
  if(connectionID < 0){
564

    
565

    
566
    printf("transmissionHandler: ConnectionID does not exist \n");
567
    exit(1);
568

    
569
  }
570

    
571
  if (connectbuf[connectionID] == NULL){
572

    
573
    printf("transmissionHandler: ConnectionID does not exist \n"); 
574
    exit(1);
575

    
576
  }else 
577
    if(connectbuf[connectionID]->status != 2){
578

    
579
      printf("transmissionHandler: Connection is not active \n");
580
      exit(1);
581
    }
582

    
583
  int external_connectionID = connectbuf[connectionID]->external_connectionID;
584

    
585
  external_socketID = connectbuf[connectionID]->external_socketID;  
586

    
587
  int pmtusize = connectbuf[connectionID]->pmtusize;
588

    
589
  //printf("pmtusize %d \n ",pmtusize);
590

    
591
  if (monitoring_data_header_set == 1){
592
        
593
    frag_size = pmtusize - MON_PACKET_HEADER_SIZE;
594

    
595
  }
596
           
597
  int messaginglayerpayloadsize = frag_size - MSGL_HEADER_SIZE;
598

    
599
  printf("..messaginglayerpayload %d \n",messaginglayerpayloadsize );
600

    
601
  udpSocket = socketfd;
602
  socketaddrgen udpgen;  
603
  if (external_socketID != NULL){
604
  udpgen = external_socketID->external_addr;
605
  }else{
606
  udpgen = external_socketID->internal_addr;
607
  }
608
  struct sockaddr_in socketaddr = udpgen.udpaddr;
609
  
610
  //set the data ID
611
  dataID = connectbuf[connectionID]->seqnr;
612
  connectbuf[connectionID]->seqnr = dataID + 1;
613
  datasize = bufsize;
614
  
615
  /* create a buffer that contains the messaging layer header and the payload fragment
616
   * char packetbuffer[fragmentsize];
617
   * bzero(packetbuffer,fragmentsize);
618
   */
619
  char* bufptr = NULL;
620
  bufptr = sendbuf;
621
 
622
  /* The sending loop aka fragmentation */
623
  while (sendCounter < bufsize){
624

    
625
    //printf("+++++test loopy \n");
626
    char msgbuf[pmtusize];
627
    bzero(msgbuf,pmtusize);
628
    char* msgbufptr = NULL;
629
    unsigned int netint = 0;
630

    
631
    send_pkt_type_and_dst_inf s_pkt_inf_;
632

    
633
    s_pkt_inf_.remote_socketID = connectbuf[connectionID]->external_socketID ;
634
    s_pkt_inf_.msgtype = msgtype;
635

    
636
    /* callback to the monitoring module if there is a monitoring module header */
637
    monitoring_pkt_header_set = (set_Monitoring_header_pkt_cb)(monitoringPktHeader,&s_pkt_inf_);
638

    
639
    //set the monitoringHeaderType accordingly
640
    if(monitoring_pkt_header_set == 1){
641

    
642
      if(monitoringHeaderType == 0){
643

    
644
        monitoringHeaderType = 2;
645

    
646
          }else 
647
        if (monitoringHeaderType == 1){
648

    
649
          monitoringHeaderType = 3;
650
        }
651
 
652
      }
653
    
654
    msgbuf[0] = packettype;
655
    char pkttype[2];
656
    pkttype[0] = packettype;
657
    pkttype[1] = '\0';
658
    printf("transmissionHandler: the packet type is %s\n",pkttype);
659

    
660
    //enter the messaging layer integers
661
    netint = external_connectionID;
662
    msgbufptr = &msgbuf[1];
663
    memcpy(msgbufptr,&netint,4);
664
    printf("transmissionHandler:  the connectionID of the other peer is %i\n",external_connectionID);
665

    
666
    netint = dataID;
667
    msgbufptr = &msgbuf[5];
668
    memcpy(msgbufptr,&netint,4);
669
    printf("transmissionHandler:  the dataID is %i\n",dataID);
670
 
671
    netint = 0;
672
    netint = offset;
673
    msgbufptr = &msgbuf[9];
674
    memcpy(msgbufptr,&netint,4);
675
    printf("transmissionHandler:  the offset is %i\n",offset);
676

    
677
    netint = 0;
678
    netint = datasize;
679
    msgbufptr = &msgbuf[13];
680
    memcpy(msgbufptr,&netint,4);
681
    printf("transmissionHandler:  the datasize is %i\n",datasize);
682

    
683
    msgbuf[17] = monitoringHeaderType;
684
    sendCounter += messaginglayerpayloadsize;
685
    
686
    if (monitoring_pkt_header_set == 1){
687
      
688
      msgbufptr = &msgbuf[18];
689
      memcpy(msgbufptr,monitoringPktHeader,MON_PACKET_HEADER_SIZE);
690
      
691
      int msgbufpos = MSGL_HEADER_SIZE + MON_PACKET_HEADER_SIZE;
692
      msgbufptr = &msgbuf[msgbufpos];
693
      memcpy(msgbufptr,bufptr,messaginglayerpayloadsize);
694

    
695
    }else{
696
    
697
    msgbufptr = &msgbuf[MSGL_HEADER_SIZE];
698
    memcpy(msgbufptr,bufptr,messaginglayerpayloadsize);
699
    
700
    }
701

    
702
    
703
    //check if this is the last fragment and adjust the size accordingly
704

    
705
    int sendsize = pmtusize;
706

    
707
    if( (offset + messaginglayerpayloadsize) > datasize){
708
      
709
      sendsize = datasize - offset + MSGL_HEADER_SIZE;
710
      
711
      if (monitoring_pkt_header_set == 1 ){
712

    
713
        sendsize += MON_PACKET_HEADER_SIZE;
714
      }
715
      
716
      printf("sendsize is %d \n",sendsize);
717
    }
718

    
719

    
720
    char testbuf[sendsize];
721
    memcpy(testbuf,msgbuf,sendsize);
722
    //printf("-=- send data: %s \n ",&testbuf[34]);
723

    
724
    sendPacket(udpSocket,msgbuf,sendsize,&socketaddr,pmtu_error_cb_th);
725

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

    
728

    
729
    //increment the data offset
730
    offset += messaginglayerpayloadsize;
731
    fprintf(stderr, "transmissionHandler: Send a packet! \n");
732

    
733
    //increment the pointer of the buffer for the fragmentsize
734
    bufptr += messaginglayerpayloadsize;
735
   
736
  
737
  }
738

    
739
 printf("transmissionHandler: SENDING FINISHED \n");  
740
 /* monitoring module callback */
741
 mon_data_inf sd_data_inf;
742

    
743
 sd_data_inf.remote_socketID = connectbuf[connectionID]->external_socketID;
744
 sd_data_inf.buffer = sendbuf;
745
 sd_data_inf.bufSize = bufsize;
746
 sd_data_inf.msgtype = msgtype;
747
 sd_data_inf.monitoringHeaderType = monitoringHeaderType;
748
 sd_data_inf.monitoringDataHeader = monitoringDataHeader;
749
 sd_data_inf.nrFragments = ceil(  bufsize / messaginglayerpayloadsize );
750
 sd_data_inf.priority = sParams->priority ;
751
 sd_data_inf.padding = sParams->padding ;
752
 sd_data_inf.confirmation = sParams->confirmation ;
753
 sd_data_inf.reliable = sParams->reliable ;
754
 gettimeofday(&sd_data_inf.arrival_time,NULL);
755

    
756
 (get_Send_data_inf_cb)((void *)&sd_data_inf);
757

    
758
  }
759

    
760

    
761
}
762
/* recv data with polling  */
763
int recv_data(const int connectionID ,char *recvbuf,int *bufsize,recv_params *rParams){
764

    
765
  if(rParams == NULL){
766

    
767
    printf("recv_data failed: recv_params is a NULL ptr \n ");
768
    return 0;
769

    
770
  }else{
771

    
772
  printf("transmissionhandler: recv data called \n");
773

    
774
   int i = 0;
775
   int returnValue = 0;
776
   double timeout = (double)recv_timeout.tv_sec;
777
   time_t endtime = time(NULL);
778

    
779
   for (i = 0; i < RECVDATABUFSIZE ; i++) {
780

    
781
     if(recvdatabuf[i] != NULL){ 
782

    
783
       if(recvdatabuf[i]->connectionID == connectionID){
784
       
785
       printf("transmissionhandler: recv data has entry  \n");
786

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

    
789
      //check if the specified connection has data and it is complete
790
      //check the data seqnr
791
      //if(connectionID == recvdatabuf[i]->connectionID && 1 == recvdatabuf[i]->status){
792

    
793
      if(1 == recvdatabuf[i]->status){
794

    
795
        //printf("transmissionHandler: recv_data set is complete  \n" );
796

    
797
        //printf("debud \n");
798

    
799
      //exchange the pointers
800
      int buffersize = 0;
801
      buffersize = recvdatabuf[i]->bufsize;
802
      *bufsize = buffersize;
803
      //recvbuf = recvdatabuf[i]->recvbuf;
804
    
805
      //printf("buffersize %d \n",buffersize);
806
      memcpy(recvbuf,recvdatabuf[i]->recvbuf,buffersize);
807
      //printf(" recvbuf %s   \n",recvbuf );
808
      
809
      double nrMissFrags = (double)recvdatabuf[i]->nrFragments / (double)recvdatabuf[i]->recvFragments;
810
      int nrMissingFragments = (int)ceil(nrMissFrags);
811

    
812
      rParams->nrMissingFragments = nrMissingFragments;
813
      rParams->nrFragments = recvdatabuf[i]->nrFragments;
814
      rParams->msgtype = recvdatabuf[i]->msgtype;
815
      rParams->connectionID = recvdatabuf[i]->connectionID;
816

    
817
      //break from the loop
818
      //printf(" recvbuf %s \n ",recvbuf);
819

    
820
      //double nrMissFrags = (double)recvdatabuf[i]->nrFragments / (double)recvdatabuf[i]->recvFragments;
821
      //int nrMissingFragments = (int)ceil(nrMissFrags);
822

    
823
      mon_data_inf recv_data_inf;
824

    
825
      recv_data_inf.remote_socketID = connectbuf[connectionID]->external_socketID;
826
      recv_data_inf.buffer = recvdatabuf[i]->recvbuf;
827
      recv_data_inf.bufSize = recvdatabuf[i]->bufsize;
828
      recv_data_inf.msgtype = recvdatabuf[i]->msgtype;
829
      recv_data_inf.monitoringHeaderType = recvdatabuf[i]->monitoringHeaderType;
830
      recv_data_inf.monitoringDataHeader = recvdatabuf[i]->monitoringDataHeader;
831
      gettimeofday(&recv_data_inf.arrival_time,NULL);
832
      recv_data_inf.firstPacketArrived = recvdatabuf[i]->firstPacketArrived;
833
      recv_data_inf.nrMissingFragments = nrMissingFragments;
834
      recv_data_inf.nrFragments = recvdatabuf[i]->nrFragments;
835
      recv_data_inf.priority = false;
836
      recv_data_inf.padding = false;
837
      recv_data_inf.confirmation = false;
838
      recv_data_inf.reliable = false;
839

    
840
      //send data recv callback to monitoring module                          
841
      (get_Recv_data_inf_cb)((void *)rParams);
842

    
843
      
844
      //free the allocated memory
845
      free(recvdatabuf[i]);
846
      recvdatabuf[i] = NULL;
847

    
848
      returnValue = 1;
849
      break;
850

    
851
      }
852

    
853
      if(recvdatabuf[i] != NULL){
854

    
855
      if(timepass > timeout){
856
     
857
        printf("transmissionHandler: recv_data timeout called  \n" );
858

    
859
        //some data about the missing chunks should be added here
860
        //exchange the pointers          
861
        int buffersize = 0;
862
        buffersize = recvdatabuf[i]->bufsize;
863
        *bufsize = buffersize;
864
        //recvbuf = recvdatabuf[i]->recvbuf;
865

    
866
        double nrMissFrags = (double)recvdatabuf[i]->nrFragments / (double)recvdatabuf[i]->recvFragments;
867
        int nrMissingFragments = (int)ceil(nrMissFrags);
868

    
869
        //printf(" recvbuf %s   \n",recvbuf );
870

    
871
        memcpy(recvbuf,recvdatabuf[i]->recvbuf,buffersize);
872

    
873
        rParams->nrMissingFragments = nrMissingFragments;
874
        rParams->nrFragments = recvdatabuf[i]->nrFragments;
875
        rParams->msgtype= recvdatabuf[i]->msgtype;
876
        rParams->connectionID = recvdatabuf[i]->connectionID;
877
        //free the allocated memory                                      
878
        free(recvdatabuf[i]);
879
        recvdatabuf[i] =NULL;
880
        
881
        //send data recv callback to monitoring module
882
        (get_Recv_data_inf_cb)((void *)rParams);
883

    
884
        returnValue = 1;
885
        break;
886

    
887
         }
888
        }
889

    
890
       }
891

    
892
     }
893
   //printf("2 recvbuf %s \n ",recvbuf);
894
   }
895
   return returnValue;
896
  }
897
}
898

    
899
void setStunServer(const int port,const char *ipaddr){
900

    
901
  stun_server.sin_family = AF_INET;          
902
  if (ipaddr == NULL){                                                       
903
    stun_server.sin_addr.s_addr = htonl(INADDR_ANY);                               
904
  }else{                                                                     
905
    stun_server.sin_addr.s_addr = htonl(inet_addr(ipaddr));                      
906
  }                                                                          
907
  stun_server.sin_port = htons(port);     
908

    
909
}
910

    
911
void setRecvTimeout(struct timeval timeout_value){
912

    
913
 recv_timeout = timeout_value;
914

    
915
}
916

    
917

    
918
void create_conn_msg(char *msgbuf,int bufsize,int local_connectionID,int external_connectionID,socketID_handle local_socketID,socketID_handle external_socketID,int msgtype){
919
  
920
  char packettype = 127;
921
  char* msgbufptr = NULL;
922
  int netint = 0;
923
  //printf("connectionID %i \n",local_connectionID);
924

    
925
  //printf("create_conn_msg: msgtype is %d \n ",msgtype);
926

    
927
  switch(msgtype){
928
    //invite
929
  case 0: 
930
    //write that this is a connect message
931
    msgbuf[0] = packettype;
932
    //write the messagetype invite
933
    msgtype = 0;
934
    msgbufptr = &msgbuf[1];
935
    memcpy(msgbufptr,&msgtype,4);
936
    //write the connectID
937
    netint = local_connectionID;
938
    msgbufptr = &msgbuf[5];
939
    memcpy(msgbufptr,&netint,4);
940
    //enter the pmut size
941
    netint = bufsize;
942
    msgbufptr = &msgbuf[9];
943
    memcpy(msgbufptr,&netint,4);
944
    //write the socketID
945
    msgbufptr = &msgbuf[13];
946
    memcpy(msgbufptr,local_socketID,sizeof(socket_ID));
947
    break;
948

    
949
    //ok
950
  case 1:
951
    //write that this is a connect message               
952
    msgbuf[0] = packettype;
953
    //write the messagetype ok    
954
    netint = 1;
955
    msgbufptr =&msgbuf[1];
956
    memcpy(msgbufptr,&netint,4);
957
    //write the connectID_from
958
    netint = external_connectionID;
959
    msgbufptr = &msgbuf[5];
960
    memcpy(msgbufptr,&netint,4);    
961
    //write the connectID_to
962
    netint = local_connectionID;
963
    msgbufptr = &msgbuf[9];
964
    memcpy(msgbufptr,&netint,4);
965
    //write the pmtu size
966
    netint = bufsize;
967
    msgbufptr = &msgbuf[13];
968
    memcpy(msgbufptr,&netint,4);
969
    break;
970

    
971
    //ack
972
  case 2:
973
    //write that this is a connect message        
974
    msgbuf[0] = packettype;
975
    //write the messagetype ack
976
    netint = 2;
977
    msgbufptr =&msgbuf[1];
978
    memcpy(msgbufptr,&netint,4);
979
    //write the connectID_from
980
    netint = local_connectionID;
981
    msgbufptr = &msgbuf[5];
982
    memcpy(msgbufptr,&netint,4);
983
    //write the connectID_to  
984
    netint = external_connectionID;
985
    msgbufptr = &msgbuf[9];
986
    memcpy(msgbufptr,&netint,4);
987
    //write the pmtu size
988
    netint = bufsize;
989
    msgbufptr = &msgbuf[13];
990
    memcpy(msgbufptr,&netint,4);
991
    break;
992
  }
993

    
994
}
995

    
996
void send_conn_msg(const int connectionID,char *msgbuf,int bufsize){
997

    
998
  int udpSocket;
999
  int returnValue;
1000
  socketID_handle external_socketID;
1001
  pmtu frag_size;
1002
  boolean int_connect;
1003

    
1004
  //printf("connectionID %i \n",connectionID);
1005
  //printf("bufsize %i \n",bufsize);
1006

    
1007
  
1008
    //set the socket variables
1009
  int_connect = connectbuf[connectionID]->internal_connect;
1010
  external_socketID = connectbuf[connectionID]->external_socketID;
1011
  
1012
  if(bufsize > 0){
1013
  frag_size = bufsize;
1014
  }else{
1015

    
1016
    frag_size = max;
1017
  }
1018
  //
1019
  udpSocket = socketfd;
1020
  
1021
  //printf("send_conn_msg: the socket fd is %i \n",udpSocket);
1022
  
1023
  //socketaddrgen udpgen = external_socketID->external_addr;
1024
  socketaddrgen udpgen;
1025
  
1026
  
1027
  if(int_connect == false){
1028
  udpgen = external_socketID->external_addr;
1029
  //set the host order
1030
  //struct sockaddr_in udpaddr;
1031
  //udpaddr = external_socketID->external_addr.udpaddr;
1032
  //udpaddr.sin_addr.s_addr  = htonl(udpaddr.sin_addr.s_addr);
1033
  //udpaddr.sin_port = htons(udpaddr.sin_port);
1034
  //udpgen.udpaddr = udpaddr;
1035
  //external_socketID->external_addr = udpgen;
1036
  }else{
1037
  udpgen = external_socketID->internal_addr;
1038
  //set the host order
1039
  //struct sockaddr_in udpaddr;
1040
  //udpaddr = external_socketID->internal_addr.udpaddr;
1041
  //udpaddr.sin_addr.s_addr  = htonl(udpaddr.sin_addr.s_addr);
1042
  //udpaddr.sin_port = htons(udpaddr.sin_port);
1043
  //udpgen.udpaddr = udpaddr;
1044
  //external_socketID->internal_addr = udpgen;
1045
  }
1046
 
1047

    
1048
  struct sockaddr_in udpaddr;
1049
  udpaddr = udpgen.udpaddr;
1050

    
1051
  printf("transmissionHandler: send_conn: the port is %i  \n",ntohs(udpaddr.sin_port));
1052
  printf("transmissionHandler: send_conn: the pmtu is %i  \n",frag_size);
1053
  
1054
  sendPacket(udpSocket,msgbuf,frag_size,&udpgen.udpaddr,pmtu_error_cb_th);
1055

    
1056
}
1057

    
1058
void recv_conn_msg(socketID_handle local_socketID,char *msgbuf,int bufsize){
1059

    
1060
  char* msgbufptr = NULL;
1061
  int connmsgtype = 0;
1062
  int i = 0;
1063
  int pmtusize = 0;
1064
  //socketaddr *socketID_to_ptr = NULL;  
1065
  int msgtypo = 0;
1066
  char msgbufnew[bufsize]; 
1067
  int internal_connectionID = 0;
1068
  socketID_handle external_socketID;
1069
  int external_connectionID = 0;
1070
  int connExist = 0;
1071
  time_t now = time(NULL);
1072
  double timediff = 0.0;
1073

    
1074
  //extract the msgtype
1075
  msgbufptr = &msgbuf[1];
1076
  memcpy(&connmsgtype,msgbufptr,4);
1077

    
1078
  //check the connection messagetype
1079
  switch(connmsgtype){
1080

    
1081
  /*if invite: 
1082
   * enter a new socket
1083
   * make new entry in connect array
1084
   * send an ok 
1085
   */
1086
  case 0:
1087
    //create a ptr to a socketaddr and allocate memory
1088
    //socketID_to_ptr = (socketaddr *)malloc(sizeof(socketaddr));
1089
    //copy the socketaddr from the message
1090

    
1091

    
1092
    //extract the pmtu size
1093
    msgbufptr = &msgbuf[9];
1094
    memcpy(&pmtusize,msgbufptr,4);
1095

    
1096
    
1097
    msgbufptr = &msgbuf[13];
1098
    external_socketID = malloc(sizeof(socket_ID));
1099
    memcpy(external_socketID,msgbufptr,sizeof(socket_ID));
1100

    
1101
    /* debug info  */
1102
    printf("transmissionHandler: __________________ \n ");
1103
    printf("transmissionHandler: received invite \n ");
1104

    
1105
    //::add check if socketID is already known
1106

    
1107
    msgbufptr = &msgbuf[5];
1108
    memcpy(&external_connectionID,msgbufptr,4);
1109

    
1110
    socketaddrgen udpgen;
1111
    udpgen = external_socketID->external_addr;
1112
    struct sockaddr_in udpaddr;                                                                                     
1113
    udpaddr = external_socketID->external_addr.udpaddr; 
1114
    //printf("+++port is %d  \n",udpaddr.sin_port);
1115

    
1116
    udpaddr.sin_addr.s_addr = htonl(udpaddr.sin_addr.s_addr);
1117
    udpaddr.sin_port = htons(udpaddr.sin_port);
1118
    udpgen.udpaddr = udpaddr;                                                   
1119
    external_socketID->external_addr = udpgen;                  
1120

    
1121
    /* check if another connection for the external connectionID exist that was established within the last 2 seconds  */
1122
    for(i = 0;i < CONNECTBUFSIZE;i++){
1123

    
1124
      if (connectbuf[i] != NULL){
1125

    
1126
        if(compare_socketIDs(connectbuf[i]->external_socketID,external_socketID) == 0){
1127
          
1128
          timediff = difftime(now,connectbuf[i]->starttime);
1129
          if(timediff < 2){
1130
            connExist = 1;
1131
          }
1132
          
1133
          }
1134
      }
1135
    }
1136
    
1137

    
1138
    if(connExist == 0){
1139

    
1140
    //create an entry in the connecttrybuf 
1141
    for(i = 0;i < CONNECTBUFSIZE;i++){
1142

    
1143
      if (connectbuf[i] == NULL){
1144

    
1145
        connectbuf[i] = (connect_data *)malloc(sizeof(connect_data));
1146
        connectbuf[i]->starttime = time(NULL);
1147
        connectbuf[i]->external_socketID = external_socketID;
1148
        connectbuf[i]->pmtusize = pmtusize;
1149
        connectbuf[i]->status = 1;
1150
        connectbuf[i]->external_connectionID = external_connectionID;
1151
        internal_connectionID = i;
1152
        break;
1153
      }
1154

    
1155
    }
1156
                                                        
1157
    //create and send the ok conn message           
1158
    msgtypo = 1;
1159
    //printf("internal connectionID %d \n", internal_connectionID);
1160
    create_conn_msg(msgbufnew,pmtusize,internal_connectionID,external_connectionID,NULL,NULL,msgtypo);
1161

    
1162
    send_conn_msg(internal_connectionID,msgbufnew,pmtusize);
1163

    
1164
    break;  
1165
                                                
1166
    }else{
1167

    
1168
      break;
1169
    }
1170
  /*if ok:
1171
   * find the entry in the connectiontry array
1172
   * create/send an ack
1173
   * make an entry in the connection array
1174
   * delete the entry in the connection_try array
1175
   */
1176
  case 1:
1177
    printf("transmissionHandler: __________________ \n ");
1178
    printf("transmissionHandler: received ok \n ");
1179
    
1180
    //extract the connect_try array position 
1181
    msgbufptr = &msgbuf[9];
1182
    memcpy(&external_connectionID,msgbufptr,4);
1183
    printf("transmissionHandler: external connectionID %i \n",external_connectionID);
1184

    
1185
    //extract pmtu size
1186
    msgbufptr = &msgbuf[13]; 
1187
    memcpy(&pmtusize,msgbufptr,4);
1188
    printf("transmissionHandler: pmtusize %i \n",pmtusize);
1189
    //extract the connecttry_ID_to
1190

    
1191
    msgbufptr = &msgbuf[5];
1192
    memcpy(&internal_connectionID,msgbufptr,4);
1193
    printf("transmissionHandler: internal connectionID %i \n",internal_connectionID);
1194

    
1195
    /* check if the connection status is not already 1  or 2  */
1196
    if(connectbuf[internal_connectionID]->status == 0){
1197

    
1198
      //set the external connectionID
1199
      connectbuf[internal_connectionID]->external_connectionID = external_connectionID;
1200

    
1201
    //change status in the connection_data
1202
    connectbuf[internal_connectionID]->status = 2;
1203

    
1204
    //change pmtusize in the connection_data
1205
    connectbuf[internal_connectionID]->pmtusize = pmtusize;
1206
    connectbuf[internal_connectionID]->pmtutrysize = pmtusize;
1207

    
1208
    (receive_Connection_cb)(internal_connectionID,NULL);
1209

    
1210
    if(    connectbuf[internal_connectionID]->connection_cb_1 != NULL){
1211
    
1212
      (connectbuf[internal_connectionID]->connection_cb_1)(internal_connectionID,connectbuf[internal_connectionID]->arg_1);
1213
      }
1214

    
1215
    if( connectbuf[internal_connectionID]->connection_cb_2 != NULL){
1216
      (connectbuf[internal_connectionID]->connection_cb_2)(internal_connectionID,connectbuf[internal_connectionID]->arg_2);
1217
      }
1218

    
1219
    //change the status
1220
    //connectbuf[internal_connectionID]->status = 2;
1221

    
1222
    //extrackt the socketID
1223
    //internal_socketID  = connectbuf[internal_connectionID]-> ;
1224
    
1225
    //send the ack
1226
    msgtypo = 2;
1227
    create_conn_msg(msgbufnew,pmtusize,internal_connectionID,external_connectionID,NULL,NULL,msgtypo);
1228
    send_conn_msg(internal_connectionID,msgbufnew,pmtusize);
1229
    printf("transmissionHandler: active connection established \n");
1230
    //connection_establisched(connectionID_this_peer);
1231

    
1232
    break;
1233

    
1234
    }else{
1235

    
1236
      break;
1237
    }
1238

    
1239
  /*if ack:
1240
   * find the entry in the connection array
1241
   * set the connection active
1242
   * change the pmtu size
1243
   */
1244
  case 2:
1245
    printf("transmissionHandler: __________________ \n ");
1246
    printf("transmissionHandler: received ack \n ");
1247

    
1248
    //extract the connect_try array position                     
1249
    msgbufptr = &msgbuf[9];
1250
    memcpy(&internal_connectionID,msgbufptr,4);
1251

    
1252
    //extract pmtu size
1253
    msgbufptr = &msgbuf[13];
1254
    memcpy(&pmtusize,msgbufptr,4);
1255

    
1256
    printf("internal connectionID: %d \n",internal_connectionID );
1257
    printf("connection status : %d \n",connectbuf[internal_connectionID]->status );
1258

    
1259
      /* checks if the connection is not already established  */
1260
      if (connectbuf[internal_connectionID]->status == 1){
1261

    
1262
        //change status of the connection
1263
        connectbuf[internal_connectionID]->status = 2;
1264

    
1265
        //change pmtusize
1266
        connectbuf[internal_connectionID]->pmtusize = pmtusize;
1267

    
1268
        printf("transmissionHandler: passiv connection established \n");
1269

    
1270
        (receive_Connection_cb)(internal_connectionID,NULL);
1271

    
1272

    
1273
        if( connectbuf[internal_connectionID]->connection_cb_1 != NULL){
1274

    
1275
          (connectbuf[internal_connectionID]->connection_cb_1)(internal_connectionID,connectbuf[internal_connectionID]->arg_1);
1276
        }
1277

    
1278
        if( connectbuf[internal_connectionID]->connection_cb_2 != NULL){
1279
          (connectbuf[internal_connectionID]->connection_cb_2)(internal_connectionID,connectbuf[internal_connectionID]->arg_2);
1280
        }
1281

    
1282
        //connection_establisched(connectionID_this_peer);
1283
        //printf("going here \n ");
1284
        //main_callback(0);
1285
        break;
1286
        
1287
      }else{
1288

    
1289
        break;
1290

    
1291
      }
1292
  }
1293

    
1294
}
1295

    
1296
/* what to do once a packet arrived 
1297
 * if it is a conn packet send it to recv_conn handler
1298
 * if it is a data packet send it to the recv_data handler
1299
 */
1300

    
1301
//get the file descriptor directly
1302

    
1303
void recv_pkg(int fd, short event, void *arg){
1304

    
1305
  printf("transmissionHandler: recv_pkg is called \n ");
1306

    
1307
  pmtu pkgsize = max;
1308
  char msgbuf[pkgsize];
1309
  int ttl;
1310
  struct sockaddr_in recv_addr;
1311
  //int rt = 0;
1312
  int recvSize;
1313

    
1314
  recvPacket(fd,msgbuf,&recvSize,&recv_addr,pmtu_error_cb_th,&ttl);
1315
  
1316
  //check if it is not just an error message
1317
  if (ttl != -1){
1318

    
1319
  unsigned short stun_bind_response =  0x0101;
1320
  unsigned short msgspot;
1321
  memcpy(&msgspot,msgbuf,sizeof(unsigned short));
1322
  char packettype; 
1323
  StunMessage stunmsg;
1324
  packettype = msgbuf[0];
1325

    
1326
    if (msgspot == stun_bind_response){
1327

    
1328
        printf("transmissionHandler: recv_pkg: parse stun message is called \n");
1329

    
1330
        recv_stun_msg(msgbuf,recvSize);
1331

    
1332
    }else 
1333
      if (packettype == 127){
1334
    //send it of to the handler
1335

    
1336
    printf("transmissionHandler: received conn pkg \n ");
1337

    
1338
    recv_conn_msg(&local_socketID,msgbuf,recvSize);
1339

    
1340
  }else 
1341
      if (packettype < 127){                                
1342
            
1343
      //need to check if this is really a data message    
1344

    
1345
      printf("transmissionHandler: received data pkg \n ");
1346
                                                  
1347
      recv_data_msg(msgbuf,recvSize,ttl);                                
1348
          
1349
      }
1350

    
1351
    //printf("recv_pkg is done \n ");
1352
  }else{
1353

    
1354
    printf("transmissionHandler: recv_pkg got only unrelated error \n ");
1355
  }
1356
  
1357

    
1358
}
1359

    
1360
void recv_stun_msg(char *msgbuf,int recvSize){
1361

    
1362
  /* create empty stun message struct  */
1363
  StunMessage resp;
1364
  memset(&resp, 0, sizeof(StunMessage));
1365
  /* parse the message  */
1366
  int returnValue = 0;
1367
  returnValue = recv_stun_message(msgbuf,recvSize,&resp);
1368

    
1369
  if(returnValue == 0){
1370
  /* read the reflexive Address into the local_socketID  */
1371
  struct sockaddr_in reflexiveAddr;
1372
  reflexiveAddr.sin_family = AF_INET;
1373
  reflexiveAddr.sin_addr.s_addr = resp.mappedAddress.ipv4.addr;
1374
  reflexiveAddr.sin_port = resp.mappedAddress.ipv4.port;
1375
  socketaddrgen reflexiveAddres;
1376
  reflexiveAddres.udpaddr = reflexiveAddr;
1377
  local_socketID.external_addr = reflexiveAddres;
1378
  NAT_traversal = true;
1379

    
1380
  /* just debug  */
1381
  UInt32 ip_addr = reflexiveAddr.sin_addr.s_addr;
1382
  char mapped_addr[16];
1383
  sprintf(mapped_addr,"%d.%d.%d.%d",(ip_addr >> 24) & 0xff,(ip_addr >> 16\
1384
                                                            )& 0xff,(ip_addr >> 8) & 0xff,ip_addr & 0xff);
1385

    
1386
  printf("transmissionHandler: mapped Address %s port %i \n ",mapped_addr\
1387
         ,reflexiveAddr.sin_port);
1388

    
1389
  }
1390

    
1391
  //callback to the upper layer indicating that the socketID is now ready to use
1392
  (receive_SocketID_cb)(&local_socketID,0);
1393

    
1394
}
1395

    
1396
//process a singe recv data message
1397
void recv_data_msg(char *msgbuf,int bufsize,int ttl){
1398

    
1399
  printf("transmissionHandler: received data message \n");
1400

    
1401
  int local_connectionID;
1402
  int seqnr;
1403
  int offset;
1404
  int size;
1405
  char *msgbufptr = NULL;
1406
  int i = 0;
1407
  boolean bool = FALSE;
1408
  char msgtype;
1409
  /*
1410
   * The monitoring header type has a range from 0 to 3
1411
   * The numbers determine if a monitoring packet hader / monitoring data header is present
1412
   * 
1413
   *     monitoring header type | data header | pkt header
1414
   *     -------------------------------------------------
1415
   *               0            |     No      |    No
1416
   *               1            |     Yes     |    No
1417
   *               2            |     No      |    Yes
1418
   *               3            |     Yes     |    Yes
1419
   */
1420
  
1421
  char monitoringHeaderType = 0;
1422
  char monitoringPktHeader[MON_PACKET_HEADER_SIZE];
1423
  char monitoringDataHeader[MON_DATA_HEADER_SIZE];
1424
  int monitoring_data_header_set = 0;
1425
  int monitoring_pkt_header_set = 0;
1426

    
1427
  //extract msgtype
1428
  msgbufptr = &msgbuf[0];
1429
  memcpy(&msgtype,msgbufptr,1);
1430
  printf("msgtype %d \n",msgtype);
1431

    
1432
  //extract connectionID
1433
  msgbufptr = &msgbuf[1];
1434
  memcpy(&local_connectionID,msgbufptr,4);
1435
  printf("local_connectionID %d \n",local_connectionID);
1436

    
1437
  //extract seqnrg
1438
  msgbufptr = &msgbuf[5];
1439
  memcpy(&seqnr,msgbufptr,4);
1440
  printf("seqnr %d \n",seqnr);
1441

    
1442
  //data offset
1443
  msgbufptr = &msgbuf[9];
1444
  memcpy(&offset,msgbufptr,4);
1445
  printf("offset is %d \n", offset);
1446

    
1447
  char firstPacketArrived = 0; 
1448
  if (offset == 0){
1449

    
1450
    firstPacketArrived = 1;
1451
  }
1452

    
1453
  //size 
1454
  msgbufptr = &msgbuf[13];
1455
  memcpy(&size,msgbufptr,4);
1456
  printf("size is %d \n",size);
1457

    
1458
  //hasMonitoringHeader
1459
  msgbufptr = &msgbuf[17];
1460
  memcpy(&monitoringHeaderType,msgbufptr,1);
1461

    
1462
  char test[2]; 
1463
  test[0] =  monitoringHeaderType;
1464
    test[1] = '\0';
1465
    printf("monitoring header type %s \n ",test);
1466

    
1467
  if(monitoringHeaderType  == 2 || monitoringHeaderType == 3){
1468
                       
1469
    msgbufptr = &msgbuf[18];
1470
    memcpy(monitoringPktHeader,msgbufptr,MON_PACKET_HEADER_SIZE);
1471
    
1472
  }
1473

    
1474
  //check if a recv_data exist and enter data
1475
  for (i = 0; i < RECVDATABUFSIZE ; i++) {
1476

    
1477
    if(recvdatabuf[i] != NULL){
1478

    
1479
    if (local_connectionID == recvdatabuf[i]->connectionID && seqnr == recvdatabuf[i]->seqnr ){
1480
      
1481
      printf("connID %d\n",recvdatabuf[i]->connectionID );
1482
      printf("seqnr %d\n",recvdatabuf[i]->seqnr);
1483

    
1484
      if(firstPacketArrived = 1){
1485

    
1486
        recvdatabuf[i]->firstPacketArrived = 1;
1487
      }
1488

    
1489
      //increment fragmentnr
1490
      recvdatabuf[i]->recvFragments = recvdatabuf[i]->recvFragments + 1;
1491
      int fragmentsize = connectbuf[local_connectionID]->pmtusize - MSGL_HEADER_SIZE;
1492
      char *bufptr = NULL;
1493
      bufptr = recvdatabuf[i]->recvbuf;
1494
      bufptr += offset;
1495
      //enter the data into the buffer
1496
      int cpysize = fragmentsize;
1497

    
1498

    
1499
      //check for last fragment
1500
      if(recvdatabuf[i]->nrFragments == recvdatabuf[i]->recvFragments ){
1501

    
1502
        cpysize = recvdatabuf[i]->bufsize - offset;
1503

    
1504
      }
1505
           //adapt copy size for the last fragment without monitoring header
1506
           if(monitoringHeaderType  == 0 || monitoringHeaderType == 1){
1507

    
1508
             //adapt copy size for the last fragment with the monitoring header
1509
             msgbufptr = &msgbuf[18];
1510
             memcpy(bufptr,msgbufptr,cpysize);
1511

    
1512
           }else
1513
             if(monitoringHeaderType  == 2 || monitoringHeaderType == 3){
1514

    
1515
               int bufpos = MSGL_HEADER_SIZE + MON_PACKET_HEADER_SIZE;
1516
               printf("bufpos %d \n",bufpos);
1517
               msgbufptr = &msgbuf[bufpos];
1518
               //cpysize = cpysize +  MON_PACKET_HEADER_SIZE;
1519
               printf("cpyssize %d \n",cpysize);
1520
               memcpy(bufptr,msgbufptr,cpysize);
1521
             }
1522
 
1523
       bool = TRUE;
1524

    
1525
          /* all fragments arrived and it are multiple fragments  */
1526

    
1527
          if (recvdatabuf[i]->nrFragments == recvdatabuf[i]->recvFragments){
1528

    
1529
            if(firstPacketArrived = 1){
1530

    
1531
              recvdatabuf[i]->firstPacketArrived = 1;
1532
            }
1533

    
1534
            printf("set the status of recvbuf 1  \n" );
1535
            recvdatabuf[i]->status = 1;
1536
                    
1537
            //extract the monitoring module data header
1538
            if (monitoringHeaderType == 1 || monitoringHeaderType == 3){
1539

    
1540

    
1541
              memcpy(monitoringDataHeader,recvdatabuf[i]->recvbuf,MON_DATA_HEADER_SIZE);
1542

    
1543
              //shorten the recv buffer and change the buffersize
1544
              recvdatabuf[i]->recvbuf += MON_DATA_HEADER_SIZE;
1545
              recvdatabuf[i]->bufsize -= MON_DATA_HEADER_SIZE;
1546
              recvdatabuf[i]->monitoringDataHeader = monitoringDataHeader;
1547

    
1548
            }
1549

    
1550
            if (recv_data_callback){
1551

    
1552
              //get the msgtype
1553
              char msgtype = recvdatabuf[i]->msgtype;
1554

    
1555
              //get the right callback
1556
              receive_data_cb receive_data_callback  = recvcbbuf[msgtype];
1557
              bufptr = recvdatabuf[i]->recvbuf;
1558
              size = recvdatabuf[i]->bufsize ;
1559
              //call the callback
1560
              //printf("msgbuf %s \n",msgbuf);
1561
              
1562
              //nr missing fragments calculate
1563

    
1564
              recv_params *rParams = malloc(sizeof(recv_params)); 
1565
              
1566
              double nrMissFrags = (double)recvdatabuf[i]->nrFragments / (double)recvdatabuf[i]->recvFragments;
1567
              int nrMissingFragments = (int)ceil(nrMissFrags);
1568
              
1569
              rParams->nrMissingFragments = nrMissingFragments;
1570
              rParams->nrFragments = recvdatabuf[i]->nrFragments;
1571
              rParams->msgtype= recvdatabuf[i]->msgtype;
1572
              rParams->connectionID = recvdatabuf[i]->connectionID;
1573
              /*
1574
              if(monitoringHeaderType  == 1 || monitoringHeaderType == 3){
1575
              rParams->monitoring_header_data = monitoringDataHeader;
1576
              }else{
1577
              rParams->monitoring_header_data = NULL;
1578
              }
1579
               */
1580

    
1581
              rParams->firstPacketArrived = recvdatabuf[i]->firstPacketArrived;
1582

    
1583
              (receive_data_callback)(bufptr,size,msgtype,(void *)rParams);
1584
          
1585
              //calback to the monitoring layer
1586
              mon_data_inf recv_data_inf_;
1587
              
1588
              recv_data_inf_.remote_socketID = connectbuf[recvdatabuf[i]->connectionID]->external_socketID;
1589
              recv_data_inf_.buffer = recvdatabuf[i]->recvbuf;
1590
              recv_data_inf_.bufSize = recvdatabuf[i]->bufsize;
1591
              recv_data_inf_.msgtype = recvdatabuf[i]->msgtype;
1592
              recv_data_inf_.monitoringHeaderType = recvdatabuf[i]->monitoringHeaderType;
1593
              recv_data_inf_.monitoringDataHeader = recvdatabuf[i]->monitoringDataHeader;
1594
              gettimeofday(&recv_data_inf_.arrival_time,NULL);
1595
              recv_data_inf_.firstPacketArrived = recvdatabuf[i]->firstPacketArrived;
1596
              recv_data_inf_.nrMissingFragments = nrMissingFragments;
1597
              recv_data_inf_.nrFragments = recvdatabuf[i]->nrFragments;
1598
              recv_data_inf_.priority = false;
1599
              recv_data_inf_.padding = false;
1600
              recv_data_inf_.confirmation = false;
1601
              recv_data_inf_.reliable = false;
1602
              
1603
              (get_Recv_data_inf_cb)((void *)&recv_data_inf_);
1604

    
1605
              free(recvdatabuf[i]);
1606
              recvdatabuf[i] = NULL;
1607

    
1608
              }
1609
        
1610
          }
1611

    
1612
    }
1613
   }
1614
  }
1615

    
1616

    
1617
  //if the dataID and connectionId dont exist: create a new recv object
1618
  if (bool == FALSE){
1619
    
1620
    for (i = 0; i < RECVDATABUFSIZE ; i++) {
1621

    
1622
      if(recvdatabuf[i] == NULL){
1623
        recvdatabuf[i] = (recvdata *)malloc(sizeof(recvdata));
1624
        recvdatabuf[i]->connectionID = local_connectionID;
1625
        recvdatabuf[i]->seqnr = seqnr;
1626
        recvdatabuf[i]->bufsize = size;
1627
        recvdatabuf[i]->recvbuf = (char *)malloc(size);
1628
        /* read the set timeout data and set it */
1629
        recvdatabuf[i]->timeout_value.tv_sec = recv_timeout.tv_sec ;
1630
        recvdatabuf[i]->timeout_value.tv_usec = recv_timeout.tv_usec ;
1631
        recvdatabuf[i]->recvID = i;
1632
        recvdatabuf[i]->starttime = time(NULL);
1633
        recvdatabuf[i]->recvFragments = 1;
1634
        recvdatabuf[i]->msgtype = msgtype;
1635
        recvdatabuf[i]->monitoringHeaderType = monitoringHeaderType;
1636
        recvdatabuf[i]->firstPacketArrived = firstPacketArrived; 
1637

    
1638
        //fill the buffer with zeros
1639
        memset(recvdatabuf[i]->recvbuf,'0',size);
1640

    
1641
        char *bufptr = NULL;
1642
        bufptr = recvdatabuf[i]->recvbuf;
1643
        bufptr += offset;
1644

    
1645
        //determine the fragmentsize
1646
        int fragmentsize = connectbuf[local_connectionID]->pmtusize - MSGL_HEADER_SIZE;
1647
        if(monitoringHeaderType  == 0 || monitoringHeaderType == 1){
1648

    
1649
          //no monitoring module header present
1650
          msgbufptr = &msgbuf[18];
1651
          memcpy(bufptr,msgbufptr,fragmentsize);
1652

    
1653
        }else
1654
          if(monitoringHeaderType  == 2 || monitoringHeaderType == 3){
1655

    
1656
            fragmentsize = fragmentsize -  MON_PACKET_HEADER_SIZE;
1657
            int bufpos = MON_PACKET_HEADER_SIZE + MSGL_HEADER_SIZE;
1658
            msgbufptr = &msgbuf[bufpos];
1659
            memcpy(bufptr,msgbufptr,fragmentsize);
1660

    
1661
            //printf("buffer %s \n ",bufptr);
1662

    
1663
          }
1664

    
1665

    
1666
        double nrFrags = (double)size / (double)fragmentsize;
1667
        int nrFragments = (int)ceil(nrFrags);
1668
        recvdatabuf[i]->nrFragments = nrFragments;
1669

    
1670
        /* if there is only one fragment the recv is finished  */
1671
        if(nrFragments == 1){
1672

    
1673
          recvdatabuf[i]->status = 1;
1674

    
1675
          //get the msgtype                                                   
1676
          char msgtype = recvdatabuf[i]->msgtype;
1677

    
1678
          //get the right callback
1679
          receive_data_cb receive_data_callback  = recvcbbuf[msgtype];
1680
          //printf("msgbuf %s \n",bufptr);
1681

    
1682
          //call the callback
1683
          recv_params *rParams = malloc(sizeof(recv_params));
1684

    
1685
          double nrMissFrags = (double)recvdatabuf[i]->nrFragments / (double)recvdatabuf[i]->recvFragments;
1686
          int nrMissingFragments = (int)ceil(nrMissFrags);
1687

    
1688
          if(monitoringHeaderType  == 1 || monitoringHeaderType == 3){
1689
          
1690
            memcpy(monitoringDataHeader,recvdatabuf[i]->recvbuf,MON_DATA_HEADER_SIZE);
1691
            //shorten the recv buffer and change the buffersize                  
1692
            recvdatabuf[i]->recvbuf += MON_DATA_HEADER_SIZE;
1693
            recvdatabuf[i]->bufsize -= MON_DATA_HEADER_SIZE;
1694
            //set this in the return parameters
1695
            //rParams->monitoring_header_data = monitoringDataHeader;
1696

    
1697
            recvdatabuf[i]->monitoringDataHeader = monitoringDataHeader;
1698

    
1699
          }else{
1700
            //rParams->monitoring_header_data = NULL;
1701
          }
1702

    
1703
          rParams->nrMissingFragments = nrMissingFragments;
1704
          rParams->nrFragments = recvdatabuf[i]->nrFragments;
1705
          rParams->msgtype= recvdatabuf[i]->msgtype;
1706
          rParams->connectionID = recvdatabuf[i]->connectionID;
1707
          rParams->firstPacketArrived = 1;
1708

    
1709
          //calback to the monitoring layer    
1710
          mon_data_inf recv_data_inf_;
1711

    
1712
          recv_data_inf_.remote_socketID = connectbuf[recvdatabuf[i]->connectionID]->external_socketID;
1713
          recv_data_inf_.buffer = recvdatabuf[i]->recvbuf;
1714
          recv_data_inf_.bufSize = recvdatabuf[i]->bufsize;
1715
          recv_data_inf_.msgtype = recvdatabuf[i]->msgtype;
1716
          recv_data_inf_.monitoringHeaderType = recvdatabuf[i]->monitoringHeaderType;
1717
          recv_data_inf_.monitoringDataHeader = recvdatabuf[i]->monitoringDataHeader;
1718
          gettimeofday(&recv_data_inf_.arrival_time,NULL);
1719
          recv_data_inf_.firstPacketArrived = recvdatabuf[i]->firstPacketArrived;
1720
          recv_data_inf_.nrMissingFragments = nrMissingFragments;
1721
          recv_data_inf_.nrFragments = recvdatabuf[i]->nrFragments;
1722
          recv_data_inf_.priority = false;
1723
          recv_data_inf_.padding = false;
1724
          recv_data_inf_.confirmation = false;
1725
          recv_data_inf_.reliable = false;
1726
                             
1727
          (get_Recv_data_inf_cb)((void *)&recv_data_inf_);
1728

    
1729
  
1730
          if(recv_data_callback){
1731

    
1732
          (receive_data_callback)(bufptr,size,msgtype,(void *)rParams);
1733
          //fill the recv_cb
1734
       
1735
          free(recvdatabuf[i]);
1736
          recvdatabuf[i] =NULL;
1737
          }
1738

    
1739

    
1740
        }
1741
        //more then one fragment
1742
        else{
1743
        
1744
          recvdatabuf[i]->status = 0 ;
1745
                      
1746
        if(recv_data_callback){
1747
          struct timeval timeout_value_print = {4,0};
1748
          struct event *ev;
1749
          ev = evtimer_new(base,recv_timeout_cb,(void *)&recvdatabuf[i]);
1750
          //recvdatabuf[i]->timeout = ev;
1751
          event_add(ev,&recvdatabuf[i]->timeout_value);
1752
          }
1753
        }
1754

    
1755
        
1756
      }
1757
      break;
1758
    }
1759

    
1760
  }
1761

    
1762
  //printf("still here 11\n");
1763

    
1764
  /* make a callback to the monitoring module after a message is recv  */
1765
  if(monitoringHeaderType  == 2 || monitoringHeaderType == 3){
1766

    
1767
    msgbufptr = &msgbuf[18];
1768
    memcpy(monitoringPktHeader,msgbufptr, MON_PACKET_HEADER_SIZE);
1769

    
1770
  }
1771

    
1772
  mon_pkt_inf msginfNow;
1773
  msginfNow.monitoringHeaderType = monitoringHeaderType;
1774
  memcpy(msginfNow.monitoringHeader,monitoringPktHeader,MON_PACKET_HEADER_SIZE);
1775
  msginfNow.ttl = ttl;
1776
  msginfNow.dataID = seqnr;
1777
  msginfNow.offset = offset;
1778
  msginfNow.datasize = size;
1779
  gettimeofday(&msginfNow.arrival_time,NULL);
1780
  (get_Recv_pkt_inf_cb)((void*)&msginfNow);
1781
}
1782

    
1783
void recv_timeout_cb(int fd,short event,void *arg){
1784

    
1785
  //int recvID;
1786
  //memcpy(&recvID,arg,4);
1787
  printf("transmissionHandler: recv_timeout_cb is called \n ");
1788

    
1789
  if(arg != NULL){
1790

    
1791
  recvdata *recvdataptr = (recvdata *) arg;
1792
  
1793
  if (recvdataptr->recvbuf != NULL){
1794
  
1795
  recvdataptr->status = 1;
1796
  char monitoringHeaderType  = recvdataptr->monitoringHeaderType;
1797
  char monitoringDataHeader[MON_DATA_HEADER_SIZE];
1798
  //check for the chunk header
1799

    
1800
  
1801
  if(monitoringHeaderType  == 1 || monitoringHeaderType == 3){
1802

    
1803
    memcpy(monitoringDataHeader ,recvdataptr->recvbuf,MON_DATA_HEADER_SIZE);
1804

    
1805
    //shorten the recv buffer and change the buffersize              
1806
                                                                    
1807
    recvdataptr->recvbuf += MON_DATA_HEADER_SIZE;
1808
    recvdataptr->bufsize -= MON_DATA_HEADER_SIZE;
1809
    
1810
    recvdataptr->monitoringDataHeader = monitoringDataHeader;
1811
  }
1812

    
1813

    
1814
  //callback to the monitoring module
1815

    
1816
  if (recv_data_callback){
1817

    
1818
    //get the msgtype         
1819
    char msgtype = recvdataptr->msgtype;
1820

    
1821
    //get the right callback
1822
    receive_data_cb receive_data_callback  = recvcbbuf[msgtype];
1823
    
1824
    recv_params *rParams = malloc(sizeof(recv_params));
1825
    double nrMissFrags = (double)recvdataptr->nrFragments / (double)recvdataptr->recvFragments;
1826
    int nrMissingFragments = (int)ceil(nrMissFrags);
1827

    
1828
    rParams->nrMissingFragments = nrMissingFragments;
1829
    rParams->nrFragments = recvdataptr->nrFragments;
1830
    rParams->msgtype= recvdataptr->msgtype;
1831
    rParams->connectionID = recvdataptr->connectionID;
1832
    rParams->firstPacketArrived = recvdataptr->firstPacketArrived;
1833

    
1834
    if(monitoringHeaderType  == 1 || monitoringHeaderType == 3){
1835

    
1836
      //rParams->monitoring_header_data = monitoringDataHeader;
1837

    
1838
    }else{
1839

    
1840
      //rParams->monitoring_header_data  = NULL;
1841

    
1842
    }
1843
    
1844

    
1845
      //call the callback                       
1846
    (receive_data_callback)(recvdataptr->recvbuf,recvdataptr->bufsize,msgtype,(void *)rParams);
1847

    
1848
    free(recvdataptr);
1849
    recvdataptr = NULL;
1850
  }
1851

    
1852

    
1853
  }
1854
  }
1855
}
1856

    
1857
void pmtu_timeout_cb(int fd,short event,void *arg){
1858

    
1859
  printf("transmissionHandler: pmtu timeout called \n");
1860

    
1861
  int connectionID; 
1862
  int msgtype; 
1863
  pmtu pmtusize;
1864
  pmtu new_pmtusize;
1865
  char msgbufx[1500];
1866

    
1867
  connect_data *my_connect_data = (connect_data *)arg;
1868
  connectionID = my_connect_data->connectionID;
1869

    
1870

    
1871
  //retreive the connectionID
1872
  //memcpy(&connectionID,arg,4);
1873
  //printf("connId %d \n",connectionID);
1874
  //&connectionID = (int *)arg;
1875

    
1876
  //int *ptr = NULL;
1877
  //ptr = (int *)arg;
1878
  
1879
  
1880
  //get status and pmtu size
1881
  msgtype = connectbuf[connectionID]->status;
1882
  pmtusize  = connectbuf[connectionID]->pmtutrysize;
1883

    
1884
  //printf("pmtusize: %i \n ",pmtusize);
1885

    
1886
  //decrement the pmtu size
1887
  new_pmtusize = pmtu_decrement(pmtusize);
1888

    
1889
  //printf("new_pmtusize: %i  \n ",new_pmtusize);
1890

    
1891
  if(new_pmtusize == error){
1892

    
1893
    if(connectbuf[connectionID]->internal_connect == true){
1894

    
1895
      connectbuf[connectionID]->internal_connect = false; 
1896

    
1897
      pmtu full = max;
1898

    
1899
      connectbuf[connectionID]->pmtutrysize = full;
1900
      connectbuf[connectionID]->pmtusize = full;
1901
      new_pmtusize = max;
1902
      //printf(" set pmtu size %i  \n",connectbuf[connectionID]->pmtutrysize);
1903
  
1904
      //printf("--> connectionID: %i  \n ",connectionID);
1905

    
1906
      int connID = connectionID;
1907
      create_conn_msg(msgbufx,1500,connID,0,&local_socketID,NULL,msgtype);
1908

    
1909
      connID = connectionID; 
1910

    
1911
      send_conn_msg(connectionID,msgbufx,1500);
1912

    
1913
      /* libevent2  */
1914
      struct event *ev1;
1915
      ev1 = evtimer_new(base,pmtu_timeout_cb, (void *)my_connect_data);
1916
      //connectbuf[connectionID]->timeout = ev;
1917
      //event_add(ev,&connectbuf[connectionID]->timeout_value);
1918
      evtimer_add(ev1,&connectbuf[connectionID]->timeout_value);
1919

    
1920

    
1921
      msgtype = 2;
1922

    
1923
    }else{
1924

    
1925
    //printf("still alive \n");
1926

    
1927
    fprintf(stderr, "transmissionHandler: Could not create connection with connectionID %i !\n",connectionID);
1928

    
1929
    (failed_Connection_cb)(connectionID,NULL);
1930
    //set the message type to a non existent message
1931
    msgtype = 2;
1932
    //delete the connection entry
1933
    free(connectbuf[connectionID]);
1934
    //envoke the callback for connection establishment
1935
    }
1936

    
1937
  }
1938

    
1939
  connectbuf[connectionID]->pmtutrysize = new_pmtusize;
1940

    
1941
  //set the buffer for the message
1942
  char msgbuf[new_pmtusize];
1943
  //struct event *ev;
1944

    
1945
  switch (msgtype){
1946

    
1947
  case 0:
1948

    
1949
    //create and send a connection message
1950
    create_conn_msg(msgbuf,new_pmtusize,connectionID,0,&local_socketID,NULL,msgtype);
1951

    
1952
    send_conn_msg(connectionID,msgbuf,new_pmtusize);
1953

    
1954
  //set a timeout event for the pmtu discovery                                             
1955
  //timeout_set(connectbuf[connectionID]->timeout,pmtu_timeout_cb,(void *)&connectionID);
1956
  
1957
  //timeout_add(connectbuf[connectionID]->timeout,&connectbuf[connectionID]->timeout_value);
1958
  
1959
    printf("transmissionHandler: connId %d \n",connectionID);
1960

    
1961

    
1962
  /* libevent2  */
1963
  struct event *ev1;
1964
  ev1 = evtimer_new(base,pmtu_timeout_cb, (void *)my_connect_data);
1965
  //connectbuf[connectionID]->timeout = ev;
1966
  //event_add(ev,&connectbuf[connectionID]->timeout_value);
1967
  evtimer_add(ev1,&connectbuf[connectionID]->timeout_value);
1968

    
1969
  break;
1970

    
1971
  case 1:
1972

    
1973
    //create and send a connection message
1974
    create_conn_msg(msgbuf,new_pmtusize,connectbuf[connectionID]->connectionID,connectbuf[connectionID]->external_connectionID,NULL,NULL,msgtype);
1975

    
1976
    send_conn_msg(connectionID,msgbuf,new_pmtusize);
1977

    
1978
    //set a timeout event for the pmtu discovery 
1979
    //timeout_set(connectbuf[connectionID]->timeout,pmtu_timeout_cb,(void *)&connectionID);
1980
    //timeout_add(connectbuf[connectionID]->timeout,&connectbuf[connectionID]->timeout_value);
1981
    
1982
    /* libevent2  */
1983
    struct event *ev2;
1984
    ev2 = evtimer_new(base,pmtu_timeout_cb, (void *)my_connect_data);
1985
    //connectbuf[connectionID]->timeout = ev;
1986
    event_add(ev2,&connectbuf[connectionID]->timeout_value);
1987

    
1988
    break;
1989

    
1990
  }
1991

    
1992
}
1993

    
1994
/*decrements the mtu size*/
1995
pmtu pmtu_decrement(pmtu pmtusize){
1996

    
1997
  pmtu pmtu_return_size;
1998

    
1999
  if (pmtusize == max){
2000

    
2001
    pmtu_return_size = dsl;
2002

    
2003
  }else if(pmtusize == dsl){
2004

    
2005
    //printf("set pmtu dsl \n");
2006
    pmtu_return_size = dslmedium;
2007

    
2008
  }else if(pmtusize == dslmedium){
2009

    
2010
    pmtu_return_size = dslslim;
2011

    
2012
  }else if(pmtusize == dslslim){
2013

    
2014
    pmtu_return_size = belowdsl;
2015

    
2016
  }else if(pmtusize == belowdsl){
2017

    
2018
    pmtu_return_size = min;
2019

    
2020
  }else{
2021
    printf("transmissionHandler: only unrealted error \n ");
2022
    pmtu_return_size = error;
2023

    
2024
  }
2025

    
2026
  return pmtu_return_size;
2027

    
2028
}
2029

    
2030
void pmtu_error_cb_th(char *msg,int msglen){
2031

    
2032
  printf("pmtu error callback \n ");
2033

    
2034
  printf("+pmtu size %d \n",msglen);
2035

    
2036
  char* msgbufptr = NULL;
2037
  int msgtype;
2038
  int connectionID;
2039
  pmtu pmtusize;
2040
  pmtu new_pmtusize;
2041
  int dead = 0;
2042

    
2043
   //check the packettype
2044
  msgbufptr = &msg[0];
2045

    
2046
  //check the msgtype
2047
  msgbufptr = &msg[1];
2048
  memcpy(&msgtype,msgbufptr,4);
2049

    
2050
  if (msgtype == 0){
2051
    
2052
    //get the connectionID
2053
    msgbufptr = &msg[5];
2054
    memcpy(&connectionID,msgbufptr,4);
2055

    
2056
    int msgtype_c = connectbuf[connectionID]->status;
2057
    pmtusize = connectbuf[connectionID]->pmtutrysize;
2058

    
2059
    if (msgtype_c != msgtype){
2060
      dead = 1;
2061
    }
2062

    
2063

    
2064
  }else if(msgtype == 1){
2065
    
2066
    //read the connectionID
2067
    msgbufptr = &msg[9];
2068
    memcpy(&connectionID,msgbufptr ,4);
2069

    
2070
    int msgtype_c = connectbuf[connectionID]->status;
2071
    pmtusize  = connectbuf[connectionID]->pmtutrysize;
2072

    
2073
    if(msgtype_c != msgtype){
2074
      dead = 1;
2075
    }
2076

    
2077
  }
2078
  
2079
  //decrement the pmtu size                    
2080
  new_pmtusize = pmtu_decrement(pmtusize);
2081

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

    
2084
  if(new_pmtusize == error){
2085

    
2086

    
2087
    fprintf(stderr, "transmissionHandler:  Could not create connection with connectionID %i !\n",connectionID);
2088

    
2089
    (failed_Connection_cb)(connectionID,NULL);
2090
    //set the message type to a non existent message                            
2091
    msgtype = 2;
2092
    //delete the connection entry                                               
2093
    free(connectbuf[connectionID]);
2094

    
2095
  }
2096

    
2097
  if (msgtype == 0 && dead != 1){
2098
  
2099
  //stop the timeout event
2100
  //timeout_del(connectbuf[connectionID]->timeout);
2101
  /*libevent2*/
2102

    
2103
  //event_del(connectbuf[connectionID]->timeout);
2104
  
2105
  //set the buffer for the message
2106
  char msgbuf[new_pmtusize];
2107

    
2108
  //create and send a connection message
2109
  create_conn_msg(msgbuf,new_pmtusize,connectionID,0,&local_socketID,NULL,0);
2110

    
2111
  send_conn_msg(connectionID,msgbuf,new_pmtusize);
2112

    
2113
  //set a timeout event for the pmtu discovery 
2114
  //timeout_set(connectbuf[connectionID]->timeout,pmtu_timeout_cb,(void *)&connectionID);
2115
  
2116
  //timeout_add(connectbuf[connectionID]->timeout,&connectbuf[connectionID]->timeout_value);
2117

    
2118
  /* libevent2  */
2119

    
2120
  struct event *ev;
2121
  ev = evtimer_new(base,pmtu_timeout_cb, (void *)connectbuf[connectionID]);
2122

    
2123
  //connectbuf[connectionID]->timeout = ev;
2124

    
2125
  event_add(ev,&connectbuf[connectionID]->timeout_value);
2126

    
2127
  }else
2128
    if(msgtype == 1 && dead != 1){
2129

    
2130
    //stop the timeout event
2131
    //timeout_del(connectbuf[connectionID]->timeout);
2132

    
2133
    /*libevent2*/
2134
    //printf("still here 11  \n");
2135
    //printf("ev %d \n",connectbuf[connectionID]->timeout);
2136
    //event_del(connectbuf[connectionID]->timeout );
2137
    //evtimer_del(connectbuf[connectionID]->timeout );
2138

    
2139
    char msgbufn[new_pmtusize];
2140

    
2141
    //create and send a connection message
2142
    create_conn_msg(msgbufn,new_pmtusize,connectbuf[connectionID]->connectionID,connectbuf[connectionID]->external_connectionID,NULL,NULL,1);
2143

    
2144
    send_conn_msg(connectionID,msgbufn,new_pmtusize);
2145

    
2146
    //set a timeout event for the pmtu discovery 
2147
    //timeout_set(connectbuf[connectionID]->timeout,pmtu_timeout_cb,(void *)&connectionID);
2148
    //timeout_add(connectbuf[connectionID]->timeout,&connectbuf[connectionID]->timeout_value);
2149

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

    
2156
    }
2157

    
2158
  
2159
}
2160

    
2161
/* compare the external IP address of two socketIDs  */
2162
int compare_external_address_socketIDs(socketID_handle sock1,socketID_handle sock2){
2163

    
2164
  int resultValue = 0;
2165
  socketaddrgen udpgen1;
2166
  socketaddrgen udpgen2;
2167
  struct sockaddr_in udpaddr1;
2168
  struct sockaddr_in udpaddr2;
2169

    
2170
  /* compare internal addr */
2171
  udpgen1 = sock1->internal_addr;
2172
  udpgen2 = sock2->internal_addr;
2173

    
2174
  udpaddr1  =  udpgen1.udpaddr;
2175
  udpaddr2  =  udpgen2.udpaddr;
2176

    
2177
  if(udpaddr1.sin_addr.s_addr != udpaddr2.sin_addr.s_addr) {
2178

    
2179
    resultValue = 1;
2180

    
2181
  }
2182

    
2183
  return resultValue;
2184

    
2185
}
2186

    
2187
/* compares 2 socketIDs: returns 0 if they are equl otherwise 1 */
2188
int compare_socketIDs(socketID_handle sock1,socketID_handle sock2){
2189

    
2190
  int resultValue = 0;
2191
  socketaddrgen udpgen1;
2192
  socketaddrgen udpgen2;
2193
  struct sockaddr_in udpaddr1;
2194
  struct sockaddr_in udpaddr2;
2195

    
2196
  /* compare internal addr */
2197
  udpgen1 = sock1->internal_addr; 
2198
  udpgen2 = sock2->internal_addr; 
2199

    
2200
  udpaddr1  =  udpgen1.udpaddr;
2201
  udpaddr2  =  udpgen2.udpaddr;
2202

    
2203
  if(udpaddr1.sin_addr.s_addr  != udpaddr2.sin_addr.s_addr) {
2204

    
2205
    resultValue = 1;
2206

    
2207
  }
2208

    
2209
  if(udpaddr1.sin_port != udpaddr2.sin_port){
2210

    
2211
    resultValue = 1;
2212

    
2213
  }
2214

    
2215
  /* compare external addr  */
2216
  udpgen1 = sock1->external_addr;
2217
  udpgen2 = sock2->external_addr;
2218
  udpaddr1  =  udpgen1.udpaddr;
2219
  udpaddr2  =  udpgen2.udpaddr;
2220

    
2221
  if(udpaddr1.sin_addr.s_addr  != udpaddr2.sin_addr.s_addr) {
2222

    
2223
    resultValue = 1;
2224

    
2225
  }
2226

    
2227
  if(udpaddr1.sin_port != udpaddr2.sin_port){
2228

    
2229
    resultValue = 1;
2230

    
2231
  }
2232

    
2233

    
2234
  return resultValue;
2235

    
2236
}
2237

    
2238
/* the timeout of the NAT traversal   */
2239
void  nat_traversal_timeout(int fd, short event, void *arg){
2240

    
2241
  //socketID_handle socketID = (void *)arg;
2242

    
2243
 if(NAT_traversal == false){
2244

    
2245
   printf("transmissionHandler: NAT traversal resend \n ");
2246
   send_stun_request(socketfd,&stun_server);
2247

    
2248
   /* enter a NAT traversal timeout that takes care of retransmission  */
2249
   struct event *ev1;
2250
   struct timeval timeout_value_NAT_traversal = {1,0};
2251
   ev1 = evtimer_new(base,nat_traversal_timeout,NULL);
2252
   event_add(ev1,&timeout_value_NAT_traversal);
2253
   //callback to the upper layer indicating that NAT traversal failed
2254
   (receive_SocketID_cb)(&local_socketID,2);
2255

    
2256
 }
2257

    
2258
}
2259

    
2260
int get_standard_ttl(socketID_handle socketID,int *ttl){
2261

    
2262
  evutil_socket_t socket = socketfd;
2263
  int returnValue = 0;
2264

    
2265
  returnValue = getTTL(socket,ttl);
2266

    
2267
  return returnValue;
2268
}
2269

    
2270
socketID_handle get_local_socketID(int *errorstatus){
2271

    
2272
  if(NAT_traversal == false){
2273

    
2274
    *errorstatus = 2;
2275

    
2276
  }else{
2277

    
2278
    *errorstatus = 0;
2279

    
2280
  }
2281

    
2282
  return &local_socketID;
2283

    
2284
}
2285

    
2286

    
2287
int get_external_IP(char* external_addr){
2288

    
2289
  socketaddrgen udpgen;
2290
  struct sockaddr_in udpaddr;
2291

    
2292
  udpgen = local_socketID.external_addr;
2293
  udpaddr = udpgen.udpaddr;
2294

    
2295
  inet_ntop(AF_INET,&(udpaddr.sin_addr),external_addr,INET_ADDRSTRLEN);
2296

    
2297
  if(external_addr == NULL){
2298

    
2299
    return -1;
2300

    
2301
  }else{
2302

    
2303
    return 0;
2304

    
2305
  }
2306

    
2307
}
2308

    
2309

    
2310
int socketID_to_String(socketID_handle socketID,char* socketID_string){
2311

    
2312
  socketaddrgen udpgen;
2313
  struct sockaddr_in udpaddr;
2314
  char external_addr[INET_ADDRSTRLEN];
2315
  udpgen = socketID->external_addr;
2316
  udpaddr = udpgen.udpaddr;
2317
  //save external port
2318
  int external_port = udpaddr.sin_port;
2319
  //convert external IP address from binary to string
2320
  inet_ntop(AF_INET,&(udpaddr.sin_addr),external_addr,INET_ADDRSTRLEN);
2321

    
2322
  char internal_addr[INET_ADDRSTRLEN];
2323
  udpgen = socketID->internal_addr;
2324
  udpaddr = udpgen.udpaddr;
2325
  //save external port
2326
  int internal_port = udpaddr.sin_port;
2327
  //convert internal IP address from binary to string
2328
  inet_ntop(AF_INET,&(udpaddr.sin_addr),internal_addr,INET_ADDRSTRLEN);
2329

    
2330
  if(external_addr == NULL || internal_addr == NULL){
2331

    
2332
    return -1;
2333

    
2334
  }else{
2335

    
2336
    char* bufptr; 
2337
    bufptr = &socketID_string[0];
2338

    
2339
    memcpy(bufptr,external_addr,INET_ADDRSTRLEN);
2340
    
2341
    bufptr = &socketID_string[16];
2342

    
2343
    memcpy(bufptr,&external_port,4);
2344

    
2345
    bufptr = &socketID_string[20]; 
2346

    
2347
    memcpy(bufptr,internal_addr,INET_ADDRSTRLEN);
2348

    
2349
    bufptr = &socketID_string[36];
2350

    
2351
    memcpy(bufptr,&internal_port,4);
2352

    
2353
    return 0;
2354

    
2355
  }
2356

    
2357
}
2358

    
2359
socketID_handle string_to_socketID(char* socketID_string){
2360

    
2361
  char external_addr[INET_ADDRSTRLEN];
2362
  int external_port;
2363
  char internal_addr[INET_ADDRSTRLEN];
2364
  int internal_port;
2365

    
2366
  //get the data into variables
2367
  char* bufptr;
2368
  bufptr = &socketID_string[0];
2369
  memcpy(external_addr,bufptr,INET_ADDRSTRLEN);
2370

    
2371
  bufptr = &socketID_string[16];
2372
  memcpy(&external_port,bufptr,4);
2373

    
2374
  bufptr = &socketID_string[20];
2375
  memcpy(internal_addr,bufptr,INET_ADDRSTRLEN);
2376

    
2377
  bufptr = &socketID_string[36];
2378
  memcpy(&internal_port,bufptr,4);
2379

    
2380

    
2381
  struct sockaddr_in udpaddr_ex;
2382
  udpaddr_ex.sin_family = AF_INET;
2383
  udpaddr_ex.sin_addr.s_addr = inet_addr(external_addr);
2384
  udpaddr_ex.sin_port = external_port;
2385

    
2386
  struct sockaddr_in udpaddr_in;
2387
  udpaddr_in.sin_family = AF_INET;
2388
  udpaddr_in.sin_addr.s_addr = inet_addr(internal_addr);
2389
  udpaddr_in.sin_port = internal_port;
2390

    
2391
  socketaddrgen udpgen_ex;
2392
  udpgen_ex.udpaddr = udpaddr_ex;
2393
  local_socketID.external_addr = udpgen_ex;
2394

    
2395
  socketaddrgen udpgen_in;
2396
  udpgen_in.udpaddr = udpaddr_in;
2397
  local_socketID.external_addr = udpgen_in;
2398

    
2399
  socketID_handle new_SocketID = malloc(sizeof(socket_ID));
2400
  new_SocketID->external_addr = udpgen_ex;
2401
  new_SocketID->internal_addr = udpgen_in;
2402
  
2403
  //return the socketID_handle
2404
  return new_SocketID;
2405
}
2406

    
2407

    
2408
int get_connection_status(int connectionID){
2409

    
2410
  //get the connection status
2411
  int stat = 0;   
2412
  stat = connectbuf[connectionID]->status;
2413
  //translate the status
2414
  int returnvalue = 0;
2415

    
2416
  if (stat != 2){
2417

    
2418
    returnvalue = -1;
2419

    
2420
  }
2421

    
2422
  return returnvalue; 
2423

    
2424
}
2425

    
2426

    
2427
int connection_exist(socketID_handle socketID){
2428

    
2429

    
2430
  int i = 0;
2431

    
2432
  /* check if another connection for the external connectionID exist that was established \
2433
     within the last 2 seconds  */
2434
  for(i = 0;i < CONNECTBUFSIZE;i++){
2435

    
2436
    if (connectbuf[i] != NULL){
2437

    
2438
      if(compare_socketIDs(connectbuf[i]->external_socketID,socketID) == 0){
2439

    
2440
        return i;
2441

    
2442
        }
2443

    
2444
      }
2445
    }
2446

    
2447
  return -1;
2448
}