Revision da5dade7

View differences:

Makefile.am
3 3
INCLUDES = -I$(top_srcdir)/include/ -I$(top_srcdir)/dclog
4 4
noinst_LIBRARIES = libml.a
5 5

  
6
libml_a_SOURCES = BUGS.txt ml.c transmissionHandler.c util/stun.c \
6
libml_a_SOURCES = BUGS.txt ml.c util/stun.c \
7 7
	util/udpSocket.c
8
# transmissionHandler.c
8 9

  
9 10
# testMessaginglayer: echoServer.c ml.h ml.c transmissionHandler.h transmissionHandler.c util/stun.h util/stun.c util/udpSocket.h util/udpSocket.c
10 11
#        ${COMPILER} -o echoServer.o echoServer.c ml.h ml.c transmissionHandler.h transmissionHandler.c util/stun.h util/stun.c util/udpSocket.h util/udpSocket.c ${EVENT} ${MATH} ${GDB}
ml.c
32 32
 *     THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
33 33
 */
34 34

  
35
#include <string.h>
35
#include <arpa/inet.h>
36
#include <netinet/in.h>
37
#include <sys/socket.h>
38
#include <fcntl.h>
39
#include <event2/event.h>
40
#include <stdlib.h>
41
#include <unistd.h>
36 42
#include <stdio.h>
37 43
#include <stddef.h>
44
#include <stdint.h>
45
#include <string.h>
38 46
#include <sys/types.h>
39
#include <netinet/in.h>
40 47
#include <arpa/inet.h>
48
#include <netdb.h>
41 49
#include <errno.h>
42
#include <stdlib.h>
43
#include <unistd.h>
44 50
#include <time.h>
45
#include <event.h>
51
#include <math.h>
52
#include "util/udpSocket.h"
53
#include "util/stun.h"
54
#include "transmissionHandler.h"
46 55

  
56
#define LOG_MODULE "[ml] "
57
#include "grapes_log.h"
47 58

  
48
#include "ml.h"
49
#include "transmissionHandler.h"
50
#include "util/udpSocket.h"
59
/**************************** START OF INTERNALS ***********************/
60

  
61
/*
62
 * a pointer to a libevent instance
63
 */
64
struct event_base *base;
65

  
66
/*
67
 * define the nr of connections the messaging layer can handle
68
 */
69
#define CONNECTBUFSIZE 10000
70
/*
71
 * define the nr of data that can be received parallel
72
 */
73
#define RECVDATABUFSIZE 10000
74
/*
75
 * define an array for message multiplexing
76
 */
77
#define MSGMULTIPLEXSIZE 127
78

  
79
/*
80
 * global variables
81
 */
82
/*
83
 * define a buffer of pointers to connect structures
84
 */
85
connect_data *connectbuf[CONNECTBUFSIZE];
86

  
87
/*
88
 * define a pointer buffer with pointers to recv_data structures
89
 */
90
recvdata *recvdatabuf[RECVDATABUFSIZE];
91

  
92
/*
93
 * define a pointer buffer for message multiplexing
94
 */
95
receive_data_cb recvcbbuf[MSGMULTIPLEXSIZE];
96

  
97
/*
98
 * stun server address
99
 */
100
struct sockaddr_in stun_server;
101

  
102
/*
103
 * receive timeout
104
 */
105
struct timeval recv_timeout;
106

  
107
/*
108
 * boolean NAT traversal successful if true
109
 */
110
boolean NAT_traversal;
111

  
112
/*
113
 * file descriptor for local socket
114
 */
115
evutil_socket_t socketfd;
116

  
117
/*
118
 * local socketID
119
 */
120
socket_ID local_socketID;
121

  
122
socketID_handle loc_socketID = &local_socketID;
123

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

  
146
/*
147
 * boolean that defines if received data is transmitted to the upper layer
148
 * via callback or via upper layer polling
149
 */
150
boolean recv_data_callback;
151

  
152
/*
153
 * helper function to get rid of a warning
154
 */
155
int min(int a, int b) {
156
	if (a > b) return b;
157
	return a;
158
}
159

  
160
void register_recv_localsocketID_cb(receive_localsocketID_cb local_socketID_cb)
161
{
162
	if (local_socketID_cb == NULL)
163
		printf("Register receive_localsocketID_cb: NULL ptr \n");
164
	else
165
	receive_SocketID_cb = local_socketID_cb;
166
}
167

  
168

  
169
void keep_connection_alive(const int connectionID)
170
{
171

  
172
    // to be done with the NAT traversal
173
    // send a message over the wire
174
    printf("\n");
175

  
176
}
177

  
178
void unsetStunServer()
179
{
180
	stun_server.sin_addr.s_addr = 0;
181
}
182

  
183
bool isStunDefined()
184
{
185
	return stun_server.sin_addr.s_addr;
186
}
187

  
188
void send_msg(int con_id, int msg_type, char* msg, int msg_len, bool truncable, send_params * sParams) {
189
	socketaddrgen udpgen;
190
	bool retry;
191
	int pkt_len, offset;
192
	struct iovec iov[4];
193

  
194
	char h_pkt[MON_HEADER_SPACE];
195
	char h_data[MON_HEADER_SPACE];
196

  
197
	struct msg_header msg_h;
198

  
199
	iov[0].iov_base = &msg_h;
200
	iov[0].iov_len = MSG_HEADER_SIZE;
201

  
202
	msg_h.local_con_id = con_id;
203
	msg_h.remote_con_id = connectbuf[con_id]->external_connectionID;
204
	msg_h.msg_type = msg_type;
205
	msg_h.msg_seq_num = connectbuf[con_id]->seqnr++;
206

  
207

  
208
	iov[1].iov_len = iov[2].iov_len = 0;
209
	iov[1].iov_base = h_pkt;
210
	iov[2].iov_base = h_data;
211

  
212

  
213
	if (connectbuf[con_id]->internal_connect)
214
		udpgen = connectbuf[con_id]->external_socketID.internal_addr;
215
	else
216
		udpgen = connectbuf[con_id]->external_socketID.external_addr;
217

  
218
	do{
219
		offset = 0;
220
		retry = false;
221
		// Monitoring layer hook
222
		if(set_Monitoring_header_data_cb != NULL) {
223
			iov[2].iov_len = ((set_Monitoring_header_data_cb) (&(connectbuf[con_id]->external_socketID), msg_type));
224
		}
225
		msg_h.len_mon_data_hdr = iov[2].iov_len;
226

  
227
		if(get_Send_data_inf_cb != NULL && iov[2].iov_len != 0) {
228
			mon_data_inf sd_data_inf;
229

  
230
			sd_data_inf.remote_socketID = &(connectbuf[con_id]->external_socketID);
231
			sd_data_inf.buffer = msg;
232
			sd_data_inf.bufSize = msg_len;
233
			sd_data_inf.msgtype = msg_type;
234
			sd_data_inf.monitoringDataHeader = iov[2].iov_base;
235
			sd_data_inf.monitoringDataHeaderLen = iov[2].iov_len;
236
			sd_data_inf.priority = sParams->priority;
237
			sd_data_inf.padding = sParams->padding;
238
			sd_data_inf.confirmation = sParams->confirmation;
239
			sd_data_inf.reliable = sParams->reliable;
240
			memset(&sd_data_inf.arrival_time, 0, sizeof(struct timeval));
241

  
242
			(get_Send_data_inf_cb) ((void *) &sd_data_inf);
243
		}
244

  
245
		do {
246
			if(set_Monitoring_header_pkt_cb != NULL) {
247
				iov[1].iov_len = (set_Monitoring_header_pkt_cb) (&(connectbuf[con_id]->external_socketID), msg_type);
248
			}
249
			pkt_len = min(connectbuf[con_id]->pmtusize - iov[2].iov_len - iov[1].iov_len - iov[0].iov_len, msg_len - offset) ;
250

  
251
			iov[3].iov_len = pkt_len;
252
			iov[3].iov_base = msg + offset;
253

  
254
			//fill header
255
			msg_h.len_mon_packet_hdr = iov[1].iov_len;
256
			msg_h.offset = offset;
257
			msg_h.msg_length = truncable ? pkt_len : msg_len;
258

  
259
			//monitoring layer hook
260
			if(get_Send_pkt_inf_cb != NULL && iov[1].iov_len) {
261
				mon_pkt_inf pkt_info;
262

  
263
				pkt_info.remote_socketID = &(connectbuf[con_id]->external_socketID);
264
				pkt_info.buffer = msg + offset;
265
				pkt_info.bufSize = pkt_len;
266
				pkt_info.msgtype = msg_type;
267
				pkt_info.dataID = connectbuf[con_id]->seqnr;
268
				pkt_info.offset = offset;
269
				pkt_info.datasize = msg_len;
270
				pkt_info.monitoringHeaderLen = iov[1].iov_len;
271
				pkt_info.monitoringHeader = iov[1].iov_base;
272
				pkt_info.ttl = -1;
273
				memset(&(pkt_info.arrival_time),0,sizeof(struct timeval));
274

  
275
				(get_Send_pkt_inf_cb) ((void *) &pkt_info);
276
			}
277

  
278

  
279
			switch(sendPacket(socketfd, iov, 4, &udpgen.udpaddr)) {
280
				case MSGLEN:
281
					connectbuf[con_id]->pmtusize = pmtu_decrement(connectbuf[con_id]->pmtusize);
282
					connectbuf[con_id]->delay = true;
283
					retry = true;
284
					offset = msg_len; // exit the while
285
					break;
286
				case FAILURE:
287
					offset = msg_len; // exit the while
288
					break;
289
				case OK:
290
					//update
291
					offset += pkt_len + iov[2].iov_len;
292
					//transmit data header only in the first packet
293
					iov[2].iov_len = 0;
294
					break;
295
			}
296
		} while(offset != msg_len + msg_h.len_mon_data_hdr && !truncable);
297
	} while(retry);
298
}
299

  
300
void send_conn_msg(int con_id, int buf_size, int command_type)
301
{
302
	send_params sparams;
303
	if(connectbuf[con_id]->ctrl_msg_buf == NULL)
304
		connectbuf[con_id]->ctrl_msg_buf = malloc(MAX);
305

  
306
	if(connectbuf[con_id]->ctrl_msg_buf == NULL) {
307
		error("ML: can not allocate memory for connection message");
308
		return;
309
	}
310

  
311
	struct conn_msg *msg_header = (struct conn_msg*) connectbuf[con_id]->ctrl_msg_buf;
312

  
313
	msg_header->comand_type = command_type;
314
	msg_header->pmtu_size = connectbuf[con_id]->pmtusize;
315

  
316
	memcpy(&(msg_header->sock_id), loc_socketID, sizeof(socket_ID));
317

  
318
	send_msg(con_id, ML_CON_MSG, connectbuf[con_id]->ctrl_msg_buf, buf_size, true, &sparams);
319
}
320

  
321
void
322
recv_conn_msg(struct msg_header *msg_h, char *msgbuf, int bufsize)
323
{
324
	struct conn_msg *con_msg;
325
	int free_con_id, con_id;
326

  
327
	time_t now = time(NULL);
328
	double timediff = 0.0;
329

  
330
	// Monitoring layer hook
331
	if(get_Recv_data_inf_cb != NULL && msg_h->len_mon_data_hdr != 0) {
332
		// update pointer to the real data
333
		msgbuf += msg_h->len_mon_data_hdr;
334
		bufsize -= msg_h->len_mon_data_hdr;
335
		con_msg = (struct conn_msg *)msgbuf;
336

  
337
		mon_data_inf recv_data_inf;
338
		recv_data_inf.remote_socketID = &(con_msg->sock_id);
339
		recv_data_inf.buffer = msgbuf;
340
		recv_data_inf.bufSize = bufsize;
341
		recv_data_inf.msgtype = msg_h->msg_type;
342
		recv_data_inf.monitoringDataHeaderLen = msg_h->len_mon_data_hdr;
343
		recv_data_inf.monitoringDataHeader = msg_h->len_mon_data_hdr ? msgbuf : NULL;
344
		gettimeofday(&recv_data_inf.arrival_time, NULL);
345
		recv_data_inf.firstPacketArrived = true;
346
		recv_data_inf.recvFragments = 1;
347
		recv_data_inf.priority = false;
348
		recv_data_inf.padding = false;
349
		recv_data_inf.confirmation = false;
350
		recv_data_inf.reliable = false;
351

  
352
		// send data recv callback to monitoring module
353
		(get_Recv_data_inf_cb) ((void *) &recv_data_inf);
354
	} else
355
		con_msg = (struct conn_msg *) msgbuf;
356

  
357
	// check the connection command type
358
	switch (con_msg->comand_type) {
359
		/*
360
		* if INVITE: enter a new socket make new entry in connect array
361
		* send an ok
362
		*/
363
		case INVITE:
364
			debug("ML: received INVITE");
365
			/*
366
			* check if another connection for the external connectionID exist
367
			* that was established within the last 2 seconds
368
			*/
369
			free_con_id = -1;
370
			for (con_id = 0; con_id < CONNECTBUFSIZE; con_id++) {
371
				if (connectbuf[con_id] != NULL) {
372
					if (mlCompareSocketIDs(&(connectbuf[con_id]->external_socketID), &(con_msg->sock_id)) == 0) {
373
						timediff = difftime(now, connectbuf[con_id]->starttime);
374
						if (timediff < 2)
375
							break;
376
					}
377
				} else if(free_con_id == -1)
378
					free_con_id = con_id;
379
			}
380

  
381
			if (con_id == CONNECTBUFSIZE) {
382
				// create an entry in the connecttrybuf
383
				if(free_con_id == -1) {
384
					error("ML: no new connect_buf available");
385
					return;
386
				}
387
				connectbuf[free_con_id] = (connect_data *) malloc(sizeof(connect_data));
388
				memset(connectbuf[free_con_id],0,sizeof(connect_data));
389
				connectbuf[free_con_id]->connection_head = connectbuf[free_con_id]->connection_last = NULL;
390
				connectbuf[free_con_id]->starttime = time(NULL);
391
				memcpy(&(connectbuf[free_con_id]->external_socketID), &(con_msg->sock_id), sizeof(socket_ID));
392
				connectbuf[free_con_id]->pmtusize = con_msg->pmtu_size;
393
				connectbuf[free_con_id]->external_connectionID = msg_h->local_con_id;
394
				connectbuf[free_con_id]->internal_connect =
395
					!compare_external_address_socketIDs(&(con_msg->sock_id), loc_socketID);
396
				con_id = free_con_id;
397
			}
398

  
399
			if(connectbuf[con_id]->status <= CONNECT) {
400
				//update status and send back answer
401
				connectbuf[con_id]->status = CONNECT;
402
				send_conn_msg(con_id, con_msg->pmtu_size, CONNECT);
403
			}
404
			break;
405
		case CONNECT:
406
			debug("ML: received CONNECT");
407

  
408
			if(msg_h->remote_con_id != -1 && connectbuf[msg_h->remote_con_id] == NULL) {
409
				error("ML: received CONNECT for unexistent connection");
410
				return;
411
			}
412

  
413
			/*
414
			* check if the connection status is not already 1 or 2
415
			*/
416
			if (connectbuf[msg_h->remote_con_id]->status == INVITE) {
417
				// set the external connectionID
418
				connectbuf[msg_h->remote_con_id]->external_connectionID = msg_h->local_con_id;
419
				// change status con_msg the connection_data
420
				connectbuf[msg_h->remote_con_id]->status = READY;
421
				// change pmtusize in the connection_data
422
				connectbuf[msg_h->remote_con_id]->pmtusize = con_msg->pmtu_size;
423

  
424
				// send the READY
425
				send_conn_msg(msg_h->remote_con_id, con_msg->pmtu_size, READY);
426

  
427
				if (receive_Connection_cb != NULL)
428
					(receive_Connection_cb) (msg_h->remote_con_id, NULL);
429

  
430
				// call all registered callbacks
431
				while(connectbuf[msg_h->remote_con_id]->connection_head != NULL) {
432
					struct receive_connection_cb_list *temp;
433
					temp = connectbuf[msg_h->remote_con_id]->connection_head;
434
					(temp->connection_cb) (msg_h->remote_con_id, temp->arg);
435
					connectbuf[msg_h->remote_con_id]->connection_head = temp->next;
436
					free(temp);
437
				}
438
				connectbuf[msg_h->remote_con_id]->connection_head =
439
					connectbuf[msg_h->remote_con_id]->connection_last = NULL;
440
			} else
441
				// send the READY
442
				send_conn_msg(msg_h->remote_con_id, con_msg->pmtu_size, READY);
443

  
444
			debug("ML: active connection established");
445
			break;
446

  
447
			/*
448
			* if READY: find the entry in the connection array set the
449
			* connection active change the pmtu size
450
			*/
451
		case READY:
452
			debug("ML: received READY");
453
			if(connectbuf[msg_h->remote_con_id] == NULL) {
454
				error("ML: received READY for unexistent connection");
455
				return;
456
			}
457
			/*
458
			* checks if the connection is not already established
459
			*/
460
			if (connectbuf[msg_h->remote_con_id]->status == CONNECT) {
461
				// change status of the connection
462
				connectbuf[msg_h->remote_con_id]->status = 2;
463
				// change pmtusize
464
				connectbuf[msg_h->remote_con_id]->pmtusize = con_msg->pmtu_size;
465

  
466
				if (receive_Connection_cb != NULL)
467
					(receive_Connection_cb) (msg_h->remote_con_id, NULL);
468

  
469
				while(connectbuf[msg_h->remote_con_id]->connection_head != NULL) {
470
					struct receive_connection_cb_list *temp;
471
					temp = connectbuf[msg_h->remote_con_id]->connection_head;
472
					(temp->connection_cb) (msg_h->remote_con_id, temp->arg);
473
					connectbuf[msg_h->remote_con_id]->connection_head = temp->next;
474
					free(temp);
475
				}
476
				connectbuf[msg_h->remote_con_id]->connection_head =
477
					connectbuf[msg_h->remote_con_id]->connection_last = NULL;
478
				debug("ML: passiv connection established");
479
			}
480
			break;
481
	}
482
}
483

  
484
void recv_stun_msg(char *msgbuf, int recvSize)
485
{
486
	/*
487
	* create empty stun message struct
488
	*/
489
	StunMessage resp;
490
	memset(&resp, 0, sizeof(StunMessage));
491
	/*
492
	* parse the message
493
	*/
494
	int returnValue = 0;
495
	returnValue = recv_stun_message(msgbuf, recvSize, &resp);
496

  
497
	if (returnValue == 0) {
498
		/*
499
		* read the reflexive Address into the local_socketID
500
		*/
501
		struct sockaddr_in reflexiveAddr;
502
		reflexiveAddr.sin_family = AF_INET;
503
		reflexiveAddr.sin_addr.s_addr = htonl(resp.mappedAddress.ipv4.addr);
504
		reflexiveAddr.sin_port = htons(resp.mappedAddress.ipv4.port);
505
		socketaddrgen reflexiveAddres;
506
		reflexiveAddres.udpaddr = reflexiveAddr;
507
		local_socketID.external_addr = reflexiveAddres;
508
		NAT_traversal = true;
509
		// callback to the upper layer indicating that the socketID is now
510
		// ready to use
511
		(receive_SocketID_cb) (&local_socketID, 0);
512
	}
513
}
514

  
515
//done
516
void recv_timeout_cb(int fd, short event, void *arg)
517
{
518
	int recv_id = (long) arg;
519
	debug("ML: recv_timeout_cb called");
520

  
521
	if (recvdatabuf[recv_id] == NULL) {
522
		return;
523
	}
524

  
525

  
526
	if(recvdatabuf[recv_id]->status == ACTIVE) {
527
		//TODO make timeout at least a DEFINE
528
		struct timeval timeout = { 4, 0 };
529
		recvdatabuf[recv_id]->status = INACTIVE;
530
		event_base_once(base, -1, EV_TIMEOUT, recv_timeout_cb,
531
			arg, &timeout);
532
		return;
533
	}
534

  
535
	if(recvdatabuf[recv_id]->status == INACTIVE) {
536
		// Monitoring layer hook
537
		if(get_Recv_data_inf_cb != NULL) {
538
			mon_data_inf recv_data_inf;
539

  
540
			recv_data_inf.remote_socketID =
541
					&(connectbuf[recvdatabuf[recv_id]->connectionID]->external_socketID);
542
			recv_data_inf.buffer = recvdatabuf[recv_id]->recvbuf;
543
			recv_data_inf.bufSize = recvdatabuf[recv_id]->bufsize;
544
			recv_data_inf.msgtype = recvdatabuf[recv_id]->msgtype;
545
			recv_data_inf.monitoringDataHeaderLen = recvdatabuf[recv_id]->monitoringDataHeaderLen;
546
			recv_data_inf.monitoringDataHeader = recvdatabuf[recv_id]->monitoringDataHeaderLen ?
547
				recvdatabuf[recv_id]->recvbuf : NULL;
548
			gettimeofday(&recv_data_inf.arrival_time, NULL);
549
			recv_data_inf.firstPacketArrived = recvdatabuf[recv_id]->firstPacketArrived;
550
			recv_data_inf.recvFragments = recvdatabuf[recv_id]->recvFragments;
551
			recv_data_inf.priority = false;
552
			recv_data_inf.padding = false;
553
			recv_data_inf.confirmation = false;
554
			recv_data_inf.reliable = false;
555

  
556
			// send data recv callback to monitoring module
557

  
558
			(get_Recv_data_inf_cb) ((void *) &recv_data_inf);
559
		}
560

  
561
		// Get the right callback
562
		receive_data_cb receive_data_callback = recvcbbuf[recvdatabuf[recv_id]->msgtype];
563

  
564
		recv_params rParams;
565

  
566
		rParams.nrMissingBytes = recvdatabuf[recv_id]->bufsize - recvdatabuf[recv_id]->arrivedBytes;
567
		rParams.recvFragments = recvdatabuf[recv_id]->recvFragments;
568
		rParams.msgtype = recvdatabuf[recv_id]->msgtype;
569
		rParams.connectionID = recvdatabuf[recv_id]->connectionID;
570
		rParams.remote_socketID =
571
			&(connectbuf[recvdatabuf[recv_id]->connectionID]->external_socketID);
572
		rParams.firstPacketArrived = recvdatabuf[recv_id]->firstPacketArrived;
573

  
574
		(receive_data_callback) (recvdatabuf[recv_id]->recvbuf + recvdatabuf[recv_id]->monitoringDataHeaderLen, recvdatabuf[recv_id]->bufsize - recvdatabuf[recv_id]->monitoringDataHeaderLen,
575
			recvdatabuf[recv_id]->msgtype, &rParams);
576

  
577
		//clean up
578
		free(recvdatabuf[recv_id]->recvbuf);
579
		free(recvdatabuf[recv_id]);
580
		recvdatabuf[recv_id] = NULL;
581
	}
582
}
583

  
584
// process a single recv data message
585
void recv_data_msg(struct msg_header *msg_h, char *msgbuf, int bufsize)
586
{
587
	debug("transmissionHandler: received data message called");
588

  
589
	int recv_id, free_recv_id = -1;
590

  
591
	if(connectbuf[msg_h->remote_con_id] == NULL) {
592
		debug("ML: Received a message not related to any opened connection!");
593
		return;
594
	}
595

  
596
	// check if a recv_data exist and enter data
597
	for (recv_id = 0; recv_id < RECVDATABUFSIZE; recv_id++)
598
		if (recvdatabuf[recv_id] != NULL) {
599
			if (msg_h->remote_con_id == recvdatabuf[recv_id]->connectionID &&
600
					msg_h->msg_seq_num == recvdatabuf[recv_id]->seqnr)
601
						break;
602
		} else
603
			if(free_recv_id == -1)
604
				free_recv_id = recv_id;
605

  
606

  
607
	if(recv_id == RECVDATABUFSIZE) {
608
		//no recv_data found: create one
609
		recv_id = free_recv_id;
610
		recvdatabuf[recv_id] = (recvdata *) malloc(sizeof(recvdata));
611
		memset(recvdatabuf[recv_id], 0, sizeof(recvdata));
612
		recvdatabuf[recv_id]->connectionID = msg_h->remote_con_id;
613
		recvdatabuf[recv_id]->seqnr = msg_h->msg_seq_num;
614
		recvdatabuf[recv_id]->monitoringDataHeaderLen = msg_h->len_mon_data_hdr;
615
		recvdatabuf[recv_id]->bufsize = msg_h->msg_length + msg_h->len_mon_data_hdr;
616
		recvdatabuf[recv_id]->recvbuf = (char *) malloc(recvdatabuf[recv_id]->bufsize);
617
		/*
618
		* read the timeout data and set it
619
		*/
620
		recvdatabuf[recv_id]->timeout_value.tv_sec = recv_timeout.tv_sec;
621
		recvdatabuf[recv_id]->timeout_value.tv_usec = recv_timeout.tv_usec;
622
		recvdatabuf[recv_id]->recvID = recv_id;
623
		recvdatabuf[recv_id]->starttime = time(NULL);
624
		recvdatabuf[recv_id]->msgtype = msg_h->msg_type;
625

  
626
		// fill the buffer with zeros
627
		memset(recvdatabuf[recv_id]->recvbuf, 0, msg_h->msg_length);
628
	}
629

  
630
	if (msg_h->offset == 0)
631
		recvdatabuf[recv_id]->firstPacketArrived = 1;
632

  
633

  
634
	// increment fragmentnr
635
	recvdatabuf[recv_id]->recvFragments++;
636
	// increment the arrivedBytes
637
	recvdatabuf[recv_id]->arrivedBytes += bufsize;
638

  
639
	// enter the data into the buffer
640
	memcpy(recvdatabuf[recv_id]->recvbuf + msg_h->offset, msgbuf, bufsize);
641

  
642
	//TODO very basic checkif all fragments arrived: has to be reviewed
643
	if(recvdatabuf[recv_id]->arrivedBytes == recvdatabuf[recv_id]->bufsize)
644
		recvdatabuf[recv_id]->status = COMPLETE; //buffer full -> msg completly arrived
645
	else
646
		recvdatabuf[recv_id]->status = ACTIVE;
647

  
648
	if (recv_data_callback) {
649
		if(recvdatabuf[recv_id]->status == COMPLETE) {
650
			// Monitoring layer hook
651
			if(get_Recv_data_inf_cb != NULL) {
652
				mon_data_inf recv_data_inf;
653

  
654
				recv_data_inf.remote_socketID =
655
					 &(connectbuf[recvdatabuf[recv_id]->connectionID]->external_socketID);
656
				recv_data_inf.buffer = recvdatabuf[recv_id]->recvbuf;
657
				recv_data_inf.bufSize = recvdatabuf[recv_id]->bufsize;
658
				recv_data_inf.msgtype = recvdatabuf[recv_id]->msgtype;
659
				recv_data_inf.monitoringDataHeaderLen = recvdatabuf[recv_id]->monitoringDataHeaderLen;
660
				recv_data_inf.monitoringDataHeader = recvdatabuf[recv_id]->monitoringDataHeaderLen ?
661
					recvdatabuf[recv_id]->recvbuf : NULL;
662
				gettimeofday(&recv_data_inf.arrival_time, NULL);
663
				recv_data_inf.firstPacketArrived = recvdatabuf[recv_id]->firstPacketArrived;
664
				recv_data_inf.recvFragments = recvdatabuf[recv_id]->recvFragments;
665
				recv_data_inf.priority = false;
666
				recv_data_inf.padding = false;
667
				recv_data_inf.confirmation = false;
668
				recv_data_inf.reliable = false;
669

  
670
				// send data recv callback to monitoring module
671

  
672
				(get_Recv_data_inf_cb) ((void *) &recv_data_inf);
673
			}
674

  
675
			// Get the right callback
676
			receive_data_cb receive_data_callback = recvcbbuf[msg_h->msg_type];
677
			if (receive_data_callback) {
678

  
679
				recv_params rParams;
680

  
681
				rParams.nrMissingBytes = recvdatabuf[recv_id]->bufsize - recvdatabuf[recv_id]->arrivedBytes;
682
				rParams.recvFragments = recvdatabuf[recv_id]->recvFragments;
683
				rParams.msgtype = recvdatabuf[recv_id]->msgtype;
684
				rParams.connectionID = recvdatabuf[recv_id]->connectionID;
685
				rParams.remote_socketID =
686
					&(connectbuf[recvdatabuf[recv_id]->connectionID]->external_socketID);
687
				rParams.firstPacketArrived = recvdatabuf[recv_id]->firstPacketArrived;
688

  
689
				(receive_data_callback) (recvdatabuf[recv_id]->recvbuf + recvdatabuf[recv_id]->monitoringDataHeaderLen, recvdatabuf[recv_id]->bufsize - recvdatabuf[recv_id]->monitoringDataHeaderLen,
690
					recvdatabuf[recv_id]->msgtype, (void *) &rParams);
691
			} else {
692
			    fprintf(stderr,"ML: Warning: callback not initialized for this message type: %d!\n",msg_h->msg_type);
693
			}
694

  
695
			//clean up
696
			free(recvdatabuf[recv_id]->recvbuf);
697
			free(recvdatabuf[recv_id]);
698
			recvdatabuf[recv_id] = NULL;
699
		} else { // not COMPLETE
700
			//start time out
701
			//TODO make timeout at least a DEFINE
702
			struct timeval timeout = { 4, 0 };
703
			event_base_once(base, -1, EV_TIMEOUT, &recv_timeout_cb, (void *) (long)recv_id, &timeout);
704
		}
705
	}
706
}
707

  
708
//done
709
void pmtu_timeout_cb(int fd, short event, void *arg)
710
{
711
	debug("ML: pmtu timeout called");
712

  
713
	int con_id = (long) arg;
714
	pmtu new_pmtusize;
715
	struct timeval timeout;
716

  
717
	if(connectbuf[con_id] == NULL) {
718
		error("ML: pmtu timeout called on non existing con_id");
719
		return;
720
	}
721

  
722
	if(connectbuf[con_id]->status == READY) {
723
		// nothing to do anymore
724
		return;
725
	}
726

  
727
	timeout = connectbuf[con_id]->timeout_value;
728

  
729
	if(connectbuf[con_id]->delay || connectbuf[con_id]->trials == MAX_TRIALS - 1) {
730
		double delay = timeout.tv_sec + timeout.tv_usec / 1000000.0;
731
		delay = delay * 5;
732
		timeout.tv_sec = floor(delay);
733
		timeout.tv_usec = fmod(delay, 1.0) * 1000000.0;
734
		if(connectbuf[con_id]->delay) {
735
			connectbuf[con_id]->delay = false;
736
			goto reschedule;
737
		}
738
	}
739

  
740
	if(connectbuf[con_id]->trials == MAX_TRIALS) {
741
		// decrement the pmtu size
742
		connectbuf[con_id]->pmtusize = pmtu_decrement(connectbuf[con_id]->pmtusize);
743
		connectbuf[con_id]->trials = 0;
744
	}
745

  
746
	//error in PMTU discovery?
747
	if (connectbuf[con_id]->pmtusize == ERROR) {
748
		if (connectbuf[con_id]->internal_connect == true) {
749
			//as of now we tried directly connecting, now let's try trough the NAT
750
			connectbuf[con_id]->internal_connect = false;
751
			connectbuf[con_id]->pmtusize = MAX;
752
		} else {
753
			//nothing to do we have to give up
754
			error("ML: Could not create connection with connectionID %i!",con_id);
755
			// envoke the callback for failed connection establishment
756
			if(failed_Connection_cb != NULL)
757
				(failed_Connection_cb) (con_id, NULL);
758
			// delete the connection entry
759
			mlCloseConnection(con_id);
760
			return;
761
		}
762
	}
763

  
764
	//retry with new pmtu size
765
	connectbuf[con_id]->trials++;
766
	send_conn_msg(con_id, connectbuf[con_id]->pmtusize, connectbuf[con_id]->status);
767

  
768
reschedule:
769
	/* reschedule */
770
	event_base_once(base, -1, EV_TIMEOUT, pmtu_timeout_cb, (void *) (long)con_id, &timeout);
771
}
772

  
773
/*
774
 * decrements the mtu size
775
 */
776
pmtu pmtu_decrement(pmtu pmtusize)
777
{
778
	pmtu pmtu_return_size;
779
	switch(pmtusize) {
780
	case MAX:
781
		return DSL;
782
	case DSL:
783
		return DSLMEDIUM;
784
	case DSLMEDIUM:
785
		return DSLSLIM;
786
	case DSLSLIM:
787
		return BELOWDSL;
788
	case BELOWDSL:
789
		return MIN;
790
	default:
791
		return ERROR;
792
	}
793
}
794

  
795
void pmtu_error_cb_th(char *msg, int msglen)
796
{
797
	debug("ML: pmtu_error callback called msg_size: %d",msglen);
798
	//TODO debug
799
	return;
800

  
801
    char *msgbufptr = NULL;
802
    int msgtype;
803
    int connectionID;
804
    pmtu pmtusize;
805
    pmtu new_pmtusize;
806
    int dead = 0;
807

  
808
    // check the packettype
809
    msgbufptr = &msg[0];
810

  
811
    // check the msgtype
812
    msgbufptr = &msg[1];
813
    memcpy(&msgtype, msgbufptr, 4);
814

  
815
    if (msgtype == 0) {
816

  
817
	// get the connectionID
818
	msgbufptr = &msg[5];
819
	memcpy(&connectionID, msgbufptr, 4);
820

  
821
	int msgtype_c = connectbuf[connectionID]->status;
822
//	pmtusize = connectbuf[connectionID]->pmtutrysize;
823

  
824
	if (msgtype_c != msgtype) {
825
	    dead = 1;
826
	}
827

  
828

  
829
    } else if (msgtype == 1) {
830

  
831
	// read the connectionID
832
	msgbufptr = &msg[9];
833
	memcpy(&connectionID, msgbufptr, 4);
834

  
835
	int msgtype_c = connectbuf[connectionID]->status;
836
//	pmtusize = connectbuf[connectionID]->pmtutrysize;
837

  
838
	if (msgtype_c != msgtype) {
839
	    dead = 1;
840
	}
841

  
842
    }
843
    // decrement the pmtu size
844
    new_pmtusize = pmtu_decrement(pmtusize);
845

  
846
//    connectbuf[connectionID]->pmtutrysize = new_pmtusize;
847

  
848
    if (new_pmtusize == ERROR) {
849
		fprintf(stderr,
850
			"transmissionHandler:  Could not create connection with connectionID %i !\n",
851
			connectionID);
852

  
853
		if(failed_Connection_cb != NULL)
854
			(failed_Connection_cb) (connectionID, NULL);
855
		// set the message type to a non existent message
856
		msgtype = 2;
857
		// delete the connection entry
858
		 mlCloseConnection(connectionID);
859
	}
860

  
861
    if (msgtype == 0 && dead != 1) {
862

  
863
	// stop the timeout event
864
	// timeout_del(connectbuf[connectionID]->timeout);
865
	/*
866
	 * libevent2
867
	 */
868

  
869
	// event_del(connectbuf[connectionID]->timeout);
870

  
871

  
872
	// create and send a connection message
873
// 	create_conn_msg(new_pmtusize, connectionID,
874
// 			&local_socketID, INVITE);
875

  
876
//	send_conn_msg(connectionID, new_pmtusize);
877

  
878
	// set a timeout event for the pmtu discovery
879
	// timeout_set(connectbuf[connectionID]->timeout,pmtu_timeout_cb,(void
880
	// *)&connectionID);
881

  
882
	// timeout_add(connectbuf[connectionID]->timeout,&connectbuf[connectionID]->timeout_value);
883

  
884
	/*
885
	 * libevent2
886
	 */
887

  
888
	struct event *ev;
889
	ev = evtimer_new(base, pmtu_timeout_cb,
890
			 (void *) connectbuf[connectionID]);
891

  
892
	// connectbuf[connectionID]->timeout = ev;
893

  
894
	event_add(ev, &connectbuf[connectionID]->timeout_value);
51 895

  
52
void init_messaging_layer(bool 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){
896
    } else if (msgtype == 1 && dead != 1) {
53 897

  
54
  init_transmissionHandler(recv_data_cb,timeout_value,port,ipaddr,stun_port,stun_ipaddr,local_socketID_cb,arg);
898
	// stop the timeout event
899
	// timeout_del(connectbuf[connectionID]->timeout);
900

  
901
	/*
902
	 * libevent2
903
	 */
904
	// printf("still here 11 \n");
905
	// printf("ev %d \n",connectbuf[connectionID]->timeout);
906
	// event_del(connectbuf[connectionID]->timeout );
907
	// evtimer_del(connectbuf[connectionID]->timeout );
908

  
909

  
910
// 	// create and send a connection message
911
// 	create_conn_msg(new_pmtusize,
912
// 			connectbuf[connectionID]->connectionID,
913
// 			NULL, CONNECT);
914

  
915
	//send_conn_msg(connectionID, new_pmtusize);
916

  
917
	// set a timeout event for the pmtu discovery
918
	// timeout_set(connectbuf[connectionID]->timeout,pmtu_timeout_cb,(void
919
	// *)&connectionID);
920
	// timeout_add(connectbuf[connectionID]->timeout,&connectbuf[connectionID]->timeout_value);
921

  
922
	/*
923
	 * libevent2
924
	 */
925
	// struct event *ev;
926
	// ev = evtimer_new(base,pmtu_timeout_cb, (void
927
	// *)connectbuf[connectionID]);
928
	// connectbuf[connectionID]->timeout = ev;
929
	// event_add(ev,&connectbuf[connectionID]->timeout_value);
930

  
931
    }
932
}
933

  
934
/*
935
 * what to do once a packet arrived if it is a conn packet send it to
936
 * recv_conn handler if it is a data packet send it to the recv_data
937
 * handler
938
 */
939

  
940
//done --
941
void recv_pkg(int fd, short event, void *arg)
942
{
943
	debug("ML: recv_pkg called");
944

  
945
	struct msg_header *msg_h;
946
	char msgbuf[MAX];
947
	char *bufptr = msgbuf;
948
	int ttl;
949
	struct sockaddr_in recv_addr;
950
	pmtu recvSize = MAX;
951
	int msg_size;
952

  
953
	recvPacket(fd, msgbuf, &recvSize, &recv_addr, pmtu_error_cb_th, &ttl);
954

  
955

  
956
	// check if it is not just an ERROR message
957
	if(recvSize < 0)
958
		return;
959

  
960
	// @TODO check if this simplistic STUN message recognition really always works, probably not
961
	unsigned short stun_bind_response = 0x0101;
962
	unsigned short * msgspot = (unsigned short *) msgbuf;
963
	if (*msgspot == stun_bind_response) {
964
		debug("ML: recv_pkg: parse stun message called");
965
		recv_stun_msg(msgbuf, recvSize);
966
		return;
967
	}
968

  
969
	msg_h = (struct msg_header *) msgbuf;
970
	bufptr += MSG_HEADER_SIZE + msg_h->len_mon_packet_hdr;
971
	msg_size = recvSize - MSG_HEADER_SIZE - msg_h->len_mon_packet_hdr;
972

  
973

  
974
	if(get_Recv_pkt_inf_cb != NULL && msg_h->len_mon_packet_hdr != 0) {
975
		mon_pkt_inf msginfNow;
976
		msginfNow.monitoringHeaderLen = msg_h->len_mon_packet_hdr;
977
		msginfNow.monitoringHeader = msg_h->len_mon_packet_hdr ? &msgbuf[0] + MSG_HEADER_SIZE : NULL;
978
		//TODO rethink this ...
979
		if(msg_h->msg_type == ML_CON_MSG) {
980
			struct conn_msg *c_msg = (struct conn_msg *) bufptr;
981
			msginfNow.remote_socketID = &(c_msg->sock_id);
982
		}
983
		else if(connectbuf[msg_h->remote_con_id] == NULL) {
984
			error("ML: received pkg called with non existent connection");
985
			return;
986
		} else
987
			msginfNow.remote_socketID = &(connectbuf[msg_h->remote_con_id]->external_socketID);
988
		msginfNow.buffer = bufptr;
989
		msginfNow.bufSize = recvSize;
990
		msginfNow.msgtype = msg_h->msg_type;
991
		msginfNow.ttl = ttl;
992
		msginfNow.dataID = msg_h->msg_seq_num;
993
		msginfNow.offset = msg_h->offset;
994
		msginfNow.datasize = msg_h->msg_length;
995
		gettimeofday(&msginfNow.arrival_time, NULL);
996
		(get_Recv_pkt_inf_cb) ((void *) &msginfNow);
997
	}
998

  
999

  
1000
	switch(msg_h->msg_type) {
1001
		case ML_CON_MSG:
1002
			debug("ML: received conn pkg");
1003
			recv_conn_msg(msg_h, bufptr, msg_size);
1004
			break;
1005
		default:
1006
			if(msg_h->msg_type < 127) {
1007
				debug("ML: received data pkg");
1008
				recv_data_msg(msg_h, bufptr, msg_size);
1009
				break;
1010
			}
1011
			debug("ML: unrecognised msg_type");
1012
			break;
1013
	}
1014
}
1015

  
1016
/*
1017
 * compare the external IP address of two socketIDs
1018
 */
1019
int
1020
compare_external_address_socketIDs(socketID_handle sock1, socketID_handle sock2)
1021
{
1022
	if( sock1->external_addr.udpaddr.sin_addr.s_addr == sock2->external_addr.udpaddr.sin_addr.s_addr)
1023
		return 0;
1024
	return 1;
1025
}
1026

  
1027
/*
1028
 * the timeout of the NAT traversal
1029
 */
1030
void nat_traversal_timeout(int fd, short event, void *arg)
1031
{
1032
	if (NAT_traversal == false) {
1033
		debug("ML: NAT traversal request resend");
1034
		send_stun_request(socketfd, &stun_server);
1035

  
1036
		/*
1037
		* enter a NAT traversal timeout that takes care of retransmission
1038
		*/
1039
		struct event *ev1;
1040
		struct timeval timeout_value_NAT_traversal = { 1, 0 };
1041
		ev1 = evtimer_new(base, nat_traversal_timeout, NULL);
1042
		event_add(ev1, &timeout_value_NAT_traversal);
1043
		if(receive_SocketID_cb)
1044
			(receive_SocketID_cb) (&local_socketID, 2);
1045
	}
1046
}
1047

  
1048
unsigned long resolve(const char *ipaddr)
1049
{
1050
	struct hostent *h = gethostbyname(ipaddr);
1051
	if (!h) {
1052
		error("Unable to resolve hostname %s\n", ipaddr);
1053
	exit(-1);
1054
    }
1055
    unsigned long *addr = (unsigned long *) (h->h_addr);
1056
    return *addr;
1057
}
1058

  
1059

  
1060
/*
1061
 * returns a handle to the socketID struct the ipaddr can be a null
1062
 * pointer. Then all available ipaddr on the machine are choosen.
1063
 */
1064
void create_socket(const int port, const char *ipaddr)
1065
{
1066
	struct sockaddr_in udpaddr;
1067
	udpaddr.sin_family = AF_INET;
1068
	if (ipaddr == NULL) {
1069
		/*
1070
		* try to guess the local IP address
1071
		*/
1072
		const char *ipaddr_iface = mlAutodetectIPAddress();
1073
		if (ipaddr_iface) {
1074
			udpaddr.sin_addr.s_addr = inet_addr(ipaddr_iface);
1075
		} else {
1076
			udpaddr.sin_addr.s_addr = INADDR_ANY;
1077
		}
1078
	} else {
1079
		udpaddr.sin_addr.s_addr = inet_addr(ipaddr);
1080
	}
1081
	udpaddr.sin_port = htons(port);
1082

  
1083
	socketaddrgen udpgen;
1084
	udpgen.udpaddr = udpaddr;
1085
	local_socketID.internal_addr = udpgen;
1086

  
1087
	socketfd = createSocket(port, ipaddr);
1088

  
1089
	struct event *ev;
1090
	ev = event_new(base, socketfd, EV_READ | EV_PERSIST, recv_pkg, NULL);
1091

  
1092
	event_add(ev, NULL);
1093

  
1094
	if (isStunDefined()) {
1095
		/*
1096
		* send the NAT traversal STUN request
1097
		*/
1098
		 send_stun_request(socketfd, &stun_server);
1099

  
1100
		/*
1101
		* enter a NAT traversal timeout that takes care of retransmission
1102
		*/
1103
		struct event *ev1;
1104
		struct timeval timeout_value_NAT_traversal = { 2, 0 };
1105
		ev1 = evtimer_new(base, nat_traversal_timeout, NULL);
1106
		event_add(ev1, &timeout_value_NAT_traversal);
1107

  
1108
		NAT_traversal = false;
1109
	} else {
1110
		/*
1111
		* Assume we have accessibility and copy internal address to external one
1112
		*/
1113
		local_socketID.external_addr = local_socketID.internal_addr;
1114
		NAT_traversal = true; // @TODO: this is not really NAT traversal, but a flag that init is over
1115
		// callback to the upper layer indicating that the socketID is now
1116
		// ready to use
1117
		(receive_SocketID_cb) (&local_socketID, 0);
1118
	}
1119
}
1120

  
1121
/**************************** END OF INTERNALS ***********************/
1122

  
1123
void mlInit(bool 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){
1124

  
1125
	base = (struct event_base *) arg;
1126
	recv_data_callback = recv_data_cb;
1127
	mlSetRecvTimeout(timeout_value);
1128
	if (stun_ipaddr) {
1129
		 mlSetStunServer(stun_port, stun_ipaddr);
1130
	} else {
1131

  
1132
	}
1133
	register_recv_localsocketID_cb(local_socketID_cb);
1134
	create_socket(port, ipaddr);
55 1135

  
56 1136
}
57 1137

  
58 1138
/* register callbacks  */
59
void register_Get_recv_pkt_inf(get_recv_pkt_inf_cb recv_pkt_inf_cb){
1139
void mlRegisterGetRecvPktInf(get_recv_pkt_inf_cb recv_pkt_inf_cb){
60 1140

  
61
  register_get_recv_pkt_inf(recv_pkt_inf_cb);
1141
	if (recv_pkt_inf_cb == NULL)
1142
		printf("Register get_recv_pkt_inf_cb failed: NULL ptr  \n");
1143
	else
1144
		get_Recv_pkt_inf_cb = recv_pkt_inf_cb;
62 1145

  
63 1146
}
64 1147

  
65 1148
void register_Get_send_pkt_inf(get_send_pkt_inf_cb  send_pkt_inf_cb){
66 1149

  
67
  register_get_send_pkt_inf(send_pkt_inf_cb);
1150
	if (send_pkt_inf_cb == NULL)
1151
		printf("Register get_send_pkt_inf_cb: NULL ptr  \n");
1152
	else
1153
		get_Send_pkt_inf_cb = send_pkt_inf_cb;
68 1154

  
69 1155
}
70 1156

  
71 1157

  
72
void register_Set_monitoring_header_pkt_cb(set_monitoring_header_pkt_cb monitoring_header_pkt_cb ){
1158
void mlRegisterSetMonitoringHeaderPktCb(set_monitoring_header_pkt_cb monitoring_header_pkt_cb ){
73 1159

  
74
  register_set_monitoring_header_pkt_cb(monitoring_header_pkt_cb);
1160
	if (monitoring_header_pkt_cb == NULL)
1161
		printf("Register set_monitoring_header_pkt_cb: NULL ptr  \n");
1162
	else
1163
		set_Monitoring_header_pkt_cb = monitoring_header_pkt_cb;
75 1164

  
76 1165
}
77 1166

  
78
void register_Get_recv_data_inf(get_recv_data_inf_cb recv_data_inf_cb){
1167
void mlRegisterGetRecvDataInf(get_recv_data_inf_cb recv_data_inf_cb){
79 1168

  
80
  register_get_recv_data_inf(recv_data_inf_cb);
1169
	if (recv_data_inf_cb == NULL)
1170
		printf("Register get_recv_data_inf_cb: NULL ptr  \n");
1171
	else
1172
		get_Recv_data_inf_cb = recv_data_inf_cb;
81 1173

  
82 1174
}
83 1175

  
84
void register_Get_send_data_inf(get_send_data_inf_cb  send_data_inf_cb){
1176
void mlRegisterGetSendDataInf(get_send_data_inf_cb  send_data_inf_cb){
85 1177

  
86
  register_get_send_data_inf(send_data_inf_cb);
1178
	if (send_data_inf_cb == NULL)
1179
		printf("Register get_send_data_inf_cb: NULL ptr  \n");
1180
	else
1181
		get_Send_data_inf_cb = send_data_inf_cb;
87 1182

  
88 1183
}
89 1184

  
90
void register_Set_monitoring_header_data_cb(set_monitoring_header_data_cb monitoring_header_data_cb){
1185
void mlRegisterSetMonitoringHeaderDataCb(set_monitoring_header_data_cb monitoring_header_data_cb){
91 1186

  
92
  register_set_monitoring_header_data_cb(monitoring_header_data_cb);
1187
	if (monitoring_header_data_cb == NULL)
1188
		printf("Register set_monitoring_header_data_cb : NULL ptr  \n");
1189
	else
1190
	set_Monitoring_header_data_cb = monitoring_header_data_cb;
93 1191

  
94 1192
}
95 1193

  
96
void register_Recv_connection_cb(receive_connection_cb recv_conn_cb){
1194
void mlRegisterRecvConnectionCb(receive_connection_cb recv_conn_cb){
97 1195

  
98
  register_recv_connection_cb(recv_conn_cb);
1196
	if (recv_conn_cb == NULL)
1197
		printf("Register receive_connection_cb: NULL ptr  \n");
1198
	else
1199
		receive_Connection_cb = recv_conn_cb;
99 1200

  
100 1201
}
101 1202

  
102
void register_Error_connection_cb(connection_failed_cb conn_failed){
1203
void mlRegisterErrorConnectionCb(connection_failed_cb conn_failed){
103 1204

  
104
  register_error_connection_cb(conn_failed);
1205
	if (conn_failed == NULL)
1206
		printf("Register connection_failed_cb: NULL ptr  \n");
1207
	else
1208
	failed_Connection_cb = conn_failed;
105 1209

  
106 1210
}
107 1211

  
108
void register_Recv_data_cb(receive_data_cb data_cb,unsigned char msgtype){
1212
void mlRegisterRecvDataCb(receive_data_cb data_cb,unsigned char msgtype){
1213

  
1214
    if (msgtype > 126) {
109 1215

  
110
  register_recv_data_cb(data_cb,msgtype);
1216
	printf
1217
	    ("transmissionHandler: Could not register recv_data callback. Msgtype is greater then 126 \n");
1218

  
1219
    }
1220

  
1221
    if (data_cb == NULL) {
1222

  
1223
	printf("Register receive data callback: NUll ptr \n ");
1224

  
1225
    } else {
1226

  
1227
	recvcbbuf[msgtype] = data_cb;
1228

  
1229
    }
111 1230

  
112 1231
}
113 1232

  
114
void close_Socket(socketID_handle socketID){
1233
void mlCloseSocket(socketID_handle socketID){
115 1234

  
116
  close_socket(socketID);
1235
	free(socketID);
117 1236

  
118 1237
}
119 1238

  
120 1239
/* connection functions */
121
int open_Connection(socketID_handle external_socketID,receive_connection_cb connection_cb,void *arg){
1240
int mlOpenConnection(socketID_handle external_socketID,receive_connection_cb connection_cb,void *arg){
1241

  
1242
	int con_id;
1243
	if (external_socketID == NULL) {
1244
		error("ML: cannot open connection: one of the socketIDs is NULL");
1245
		return -1;
1246
	}
1247
	if (NAT_traversal == false) {
1248
		error("ML: cannot open connection: NAT traversal for socketID still in progress");
1249
		return -1;
1250
	}
1251
	if (connection_cb == NULL) {
1252
		error("ML: cannot open connection: connection_cb is NULL");
1253
		return -1;
1254
	}
1255

  
1256
	// check if that connection already exist
1257

  
1258
	con_id = mlConnectionExist(external_socketID, false);
1259
	if (con_id >= 0) {
1260
		// if so check if it is ready to use
1261
		if (connectbuf[con_id]->status == READY) {
1262
				// if so use the callback immidiatley
1263
				(connection_cb) (con_id, arg);
1264

  
1265
		// otherwise just write the connection cb and the arg pointer
1266
		// into the connection struct
1267
		} else {
1268
			struct receive_connection_cb_list *temp;
1269
			temp = malloc(sizeof(struct receive_connection_cb_list));
1270
			temp->next = NULL;
1271
			temp->connection_cb = connection_cb;
1272
			temp->arg = arg;
1273
			if(connectbuf[con_id]->connection_last != NULL) {
1274
				connectbuf[con_id]->connection_last->next = temp;
1275
				connectbuf[con_id]->connection_last = temp;
1276
			} else
1277
				connectbuf[con_id]->connection_last = connectbuf[con_id]->connection_head = temp;
1278
		}
1279
		return con_id;
1280
	}
1281
	// make entry in connection_establishment array
1282
	for (con_id = 0; con_id < CONNECTBUFSIZE; con_id++) {
1283
		if (connectbuf[con_id] == NULL) {
1284
			connectbuf[con_id] = (connect_data *) malloc(sizeof(connect_data));
1285
			memset(connectbuf[con_id],0,sizeof(connect_data));
1286
			connectbuf[con_id]->starttime = time(NULL);
1287
			memcpy(&connectbuf[con_id]->external_socketID, external_socketID, sizeof(socket_ID));
1288
			connectbuf[con_id]->pmtusize = MAX;
1289
			connectbuf[con_id]->status = INVITE;
1290
			connectbuf[con_id]->seqnr = 0;
1291
			connectbuf[con_id]->internal_connect = !compare_external_address_socketIDs(external_socketID, &local_socketID);
1292
			/*
1293
			* timeout values for the pmtu discovery
1294
			*/
1295
			connectbuf[con_id]->timeout_value.tv_sec = 15;
1296
			connectbuf[con_id]->timeout_value.tv_usec = 0;
1297
			connectbuf[con_id]->connectionID = con_id;
1298

  
1299
			connectbuf[con_id]->connection_head = connectbuf[con_id]->connection_last = malloc(sizeof(struct receive_connection_cb_list));
1300
			connectbuf[con_id]->connection_last->next = NULL;
1301
			connectbuf[con_id]->connection_last->connection_cb = connection_cb;
1302
			connectbuf[con_id]->connection_last->arg = arg;
1303
			connectbuf[con_id]->external_connectionID = -1;
1304
			break;
1305
		}
1306
	} //end of for
1307

  
1308
	if (con_id == CONNECTBUFSIZE) {
1309
		error("ML: Could not open connection: connbuffer full");
1310
		return -1;
1311
	}
1312

  
1313
	// create and send a connection message
1314
	send_conn_msg(con_id, MAX, INVITE);
1315

  
1316
	struct event *ev;
1317
	ev = evtimer_new(base, pmtu_timeout_cb, (void *) (long)con_id);
1318
	event_add(ev, &connectbuf[con_id]->timeout_value);
1319

  
1320
	return con_id;
1321

  
1322
}
122 1323

  
123
  return open_connection(external_socketID,connection_cb,arg);
1324
void mlCloseConnection(const int connectionID){
1325

  
1326
	// remove it from the connection array
1327
	if(connectbuf[connectionID]) {
1328
		if(connectbuf[connectionID]->ctrl_msg_buf)
1329
			free(connectbuf[connectionID]->ctrl_msg_buf);
1330
		free(connectbuf[connectionID]);
1331
		connectbuf[connectionID] = NULL;
1332
	}
124 1333

  
125 1334
}
126 1335

  
127
void close_Connection(const int connectionID){
1336
void mlSendData(const int connectionID,char *sendbuf,int bufsize,unsigned char msgtype,send_params *sParams){
1337

  
1338
	if (sParams == NULL) {
1339
		error("ML: send data failed: send_params is a NULL ptr");
1340
		return;
1341
	}
1342

  
1343
	if (connectionID < 0) {
1344
		error("ML: send data failed: connectionID does not exist");
1345
		return;
1346
	}
1347

  
1348
	if (connectbuf[connectionID] == NULL) {
1349
		error("ML: send data failed: connectionID does not exist");
1350
		return;
1351
	}
1352
	if (connectbuf[connectionID]->status != READY) {
1353
	    error("ML: send data failed: connection is not active");
1354
	    return;
1355
	}
128 1356

  
129
  close_connection(connectionID);
1357
	send_msg(connectionID, msgtype, sendbuf, bufsize, false, sParams);
130 1358

  
131 1359
}
132 1360

  
133 1361
/* transmit data functions  */
134
int send_All_data(const int connectionID,send_all_data_container *container,int nr_entries,unsigned char msgtype,send_params *sParams){
1362
int mlSendAllData(const int connectionID,send_all_data_container *container,int nr_entries,unsigned char msgtype,send_params *sParams){
135 1363

  
136
  return send_all_data(connectionID,container,nr_entries,msgtype,sParams);
137 1364

  
138
}
139 1365

  
140
void send_Data(const int connectionID,char *sendbuf,int bufsize,unsigned char msgtype,send_params *sParams){
141 1366

  
142
   send_data(connectionID,sendbuf,bufsize,msgtype,sParams);
1367
    if (nr_entries < 1 || nr_entries > 5) {
1368

  
1369
	printf
1370
	    ("send_all_data ERROR: nr_enties is not between 1 and 5 \n ");
1371
	return 0;
1372

  
1373
    } else {
1374

  
1375
	if (nr_entries == 1) {
1376

  
1377
		mlSendData(connectionID, container->buffer_1,
1378
		      container->length_1, msgtype, sParams);
1379

  
1380
	    return 1;
1381

  
1382
	} else if (nr_entries == 2) {
1383

  
1384
	    int buflen = container->length_1 + container->length_2;
1385
	    char buf[buflen];
1386
	    memcpy(buf, container->buffer_1, container->length_1);
1387
	    memcpy(&buf[container->length_1], container->buffer_2,
1388
		   container->length_2);
1389
	    mlSendData(connectionID, buf, buflen, msgtype, sParams);
1390

  
1391
	    return 1;
1392

  
1393
	} else if (nr_entries == 3) {
1394

  
1395
	    int buflen =
1396
		container->length_1 + container->length_2 +
1397
		container->length_3;
1398
	    char buf[buflen];
1399
	    memcpy(buf, container->buffer_1, container->length_1);
1400
	    memcpy(&buf[container->length_1], container->buffer_2,
1401
		   container->length_2);
1402
	    memcpy(&buf[container->length_2], container->buffer_3,
1403
		   container->length_3);
1404
	    mlSendData(connectionID, buf, buflen, msgtype, sParams);
1405

  
1406

  
1407
	    return 1;
1408

  
1409
	} else if (nr_entries == 4) {
1410

  
1411
	    int buflen =
1412
		container->length_1 + container->length_2 +
1413
		container->length_3 + container->length_4;
1414
	    char buf[buflen];
1415
	    memcpy(buf, container->buffer_1, container->length_1);
1416
	    memcpy(&buf[container->length_1], container->buffer_2,
1417
		   container->length_2);
1418
	    memcpy(&buf[container->length_2], container->buffer_3,
1419
		   container->length_3);
1420
	    memcpy(&buf[container->length_3], container->buffer_4,
1421
		   container->length_4);
1422
	    mlSendData(connectionID, buf, buflen, msgtype, sParams);
1423

  
1424
	    return 1;
1425

  
1426
	} else {
1427

  
1428
	    int buflen =
1429
		container->length_1 + container->length_2 +
1430
		container->length_3 + container->length_4 +
1431
		container->length_5;
1432
	    char buf[buflen];
1433
	    memcpy(buf, container->buffer_1, container->length_1);
1434
	    memcpy(&buf[container->length_1], container->buffer_2,
1435
		   container->length_2);
1436
	    memcpy(&buf[container->length_2], container->buffer_3,
1437
		   container->length_3);
1438
	    memcpy(&buf[container->length_3], container->buffer_4,
1439
		   container->length_4);
1440
	    memcpy(&buf[container->length_4], container->buffer_5,
1441
		   container->length_5);
1442
	    mlSendData(connectionID, buf, buflen, msgtype, sParams);
1443

  
1444
	    return 1;
1445
	}
1446

  
1447
    }
143 1448

  
144 1449
}
145 1450

  
146
int recv_Data(const int connectionID,char *recvbuf,int *bufsize,recv_params *rParams){
1451
int mlRecvData(const int connectionID,char *recvbuf,int *bufsize,recv_params *rParams){
1452

  
1453
	//TODO yet to be converted
1454
	return 0;
1455
#if 0
1456
	if (rParams == NULL) {
1457
		error("ML: recv_data failed: recv_params is a NULL ptr");
1458
		return 0;
1459
    } else {
1460

  
1461
	printf("transmissionhandler: recv data called \n");
1462

  
1463
	int i = 0;
1464
	int returnValue = 0;
1465
	double timeout = (double) recv_timeout.tv_sec;
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff