Revision dabdae6c

View differences:

src/net_helper-ml.c
1
/*
2
 *  Copyright (c) 2009 Marco Biazzini
3
 *
4
 *  This is free software; see lgpl-2.1.txt
5
 */
6

  
7
#include <event2/event.h>
8
#ifndef _WIN32
9
#include <arpa/inet.h>
10
#endif
11
#include <unistd.h>
12
#include <stdlib.h>
13
#include <stdio.h>
14
#include <stdbool.h>
15
#include <string.h>
16
#include <assert.h>
17
#include <signal.h>
18

  
19
#include "net_helper.h"
20
#include "ml.h"
21
#include "config.h"
22

  
23
#include "grapes_msg_types.h"
24

  
25

  
26
#ifdef MONL
27
#include "mon.h"
28
#include "repoclient.h"
29
#endif
30

  
31
#include "napa.h"
32
#include "napa_log.h"
33

  
34
/**
35
 * libevent pointer
36
 */
37
struct event_base *base;
38

  
39
#define NH_BUFFER_SIZE 1000
40
#define NH_LOOKUP_SIZE 1000
41
#define NH_PACKET_TIMEOUT {0, 500*1000}
42
#define NH_ML_INIT_TIMEOUT {1, 0}
43

  
44
#define FDSSIZE 16
45

  
46
static bool connect_on_know = false;	//whether to try to connect as soon as we get to know a nodeID
47

  
48
static int sIdx = 0;
49
static int rIdxML = 0;	//reveive from ML to this buffer position
50
static int rIdxUp = 0;	//hand up to layer above at this buffer position
51

  
52
typedef struct nodeID {
53
	socketID_handle addr;
54
	int connID;	// connection associated to this node, -1 if myself
55
	int refcnt;
56
#ifdef MONL
57
	//n quick and dirty static vector for measures TODO: make it dinamic
58
	MonHandler mhs[20];
59
	int n_mhs;
60
#endif
61
//	int addrSize;
62
//	int addrStringSize;
63
} nodeID;
64

  
65
typedef struct msgData_cb {
66
	int bIdx;	// index of the message in the proper buffer
67
	unsigned char msgType; // message type
68
	int mSize;	// message size
69
	bool conn_cb_called;
70
	bool cancelled;
71
} msgData_cb;
72

  
73
static struct nodeID **lookup_array;
74
static int lookup_max = NH_LOOKUP_SIZE;
75
static int lookup_curr = 0;
76

  
77
static nodeID *me; //TODO: is it possible to get rid of this (notwithstanding ml callback)??
78
static int timeoutFired = 0;
79
static bool fdTriggered = false;
80

  
81
// pointers to the msgs to be send
82
static uint8_t *sendingBuffer[NH_BUFFER_SIZE];
83
// pointers to the received msgs + sender nodeID
84
struct receivedB {
85
	struct nodeID *id;
86
	int len;
87
	uint8_t *data;
88
};
89
static struct receivedB receivedBuffer[NH_BUFFER_SIZE];
90
/**/ static int recv_counter =0;
91

  
92

  
93
static void connReady_cb (int connectionID, void *arg);
94
static struct nodeID *new_node(socketID_handle peer) {
95
	send_params params = {0,0,0,0};
96
	struct nodeID *res = malloc(sizeof(struct nodeID));
97
	if (!res) {
98
		 fprintf(stderr, "Net-helper : memory error\n");
99
		 return NULL;
100
	}
101
	memset(res, 0, sizeof(struct nodeID));
102

  
103
	res->addr = malloc(SOCKETID_SIZE);
104
	if (! res->addr) {
105
		free (res);
106
		fprintf(stderr, "Net-helper : memory error while creating a new nodeID \n");
107
		return NULL;
108
	}
109
	memset(res->addr, 0, SOCKETID_SIZE);
110
	memcpy(res->addr, peer ,SOCKETID_SIZE);
111

  
112
	res->refcnt = 1;
113

  
114
	if (connect_on_know) {
115
		res->connID = mlOpenConnection(peer, &connReady_cb, NULL, params);
116
	}
117

  
118
	return res;
119
}
120

  
121

  
122
static struct nodeID **id_lookup(socketID_handle target) {
123

  
124
	int i,here=-1;
125
	for (i=0;i<lookup_curr;i++) {
126
		if (lookup_array[i] == NULL) {
127
			if (here < 0) {
128
				here = i;
129
			}
130
		} else if (!mlCompareSocketIDs(lookup_array[i]->addr,target)) {
131
			return &lookup_array[i];
132
		}
133
	}
134

  
135
	if (here == -1) {
136
		here = lookup_curr++;
137
	}
138

  
139
	if (lookup_curr > lookup_max) {
140
		lookup_max *= 2;
141
		lookup_array = realloc(lookup_array,lookup_max*sizeof(struct nodeID*));
142
	}
143

  
144
	lookup_array[here] = new_node(target);
145
	return &lookup_array[here];
146
}
147

  
148
static struct nodeID *id_lookup_dup(socketID_handle target) {
149
	return nodeid_dup(*id_lookup(target));
150
}
151

  
152

  
153
/**
154
 * Look for a free slot in the received buffer and allocates it for immediate use
155
 * @return the index of a free slot in the received msgs buffer, -1 if no free slot available.
156
 */
157
static int next_R() {
158
	if (receivedBuffer[rIdxML].data==NULL) {
159
		int ret = rIdxML;
160
		rIdxML = (rIdxML+1)%NH_BUFFER_SIZE;
161
		return ret;
162
	} else {
163
		//TODO: handle receive overload situation!
164
		return -1;
165
	}
166
}
167

  
168
/**
169
 * Look for a free slot in the sending buffer and allocates it for immediate use
170
 * @return the index of a free slot in the sending msgs buffer, -1 if no free slot available.
171
 */
172
static int next_S() {
173
	if (sendingBuffer[sIdx]) {
174
		int count;
175
		for (count=0;count<NH_BUFFER_SIZE;count++) {
176
			sIdx = (sIdx+1)%NH_BUFFER_SIZE;
177
			if (sendingBuffer[sIdx]==NULL)
178
				break;
179
		}
180
		if (count==NH_BUFFER_SIZE) {
181
			return -1;
182
		}
183
	}
184
	return sIdx;
185
}
186

  
187

  
188
/**
189
 * Callback used by ml to confirm its initialization. Create a valid self nodeID and register to receive data from remote peers.
190
 * @param local_socketID
191
 * @param errorstatus
192
 */
193
static void init_myNodeID_cb (socketID_handle local_socketID,int errorstatus) {
194
	switch (errorstatus) {
195
	case 0:
196
		me->addr = malloc(SOCKETID_SIZE);
197
		if (! me->addr) {
198
			fprintf(stderr, "Net-helper : memory error while creating my new nodeID \n");
199
			return;
200
		}
201

  
202
		memcpy(me->addr,local_socketID,SOCKETID_SIZE);
203
	//	me->addrSize = SOCKETID_SIZE;
204
	//	me->addrStringSize = SOCKETID_STRING_SIZE;
205
		me->connID = -1;
206
		me->refcnt = 1;
207
	//	fprintf(stderr,"Net-helper init : received my own socket: %s.\n",node_addr(me));
208
		break;
209
	case -1:
210
		//
211
		fprintf(stderr,"Net-helper init : socket error occurred in ml while creating socket\n");
212
		exit(1);
213
		break;
214
	case 1:
215
		//
216
		fprintf(stderr,"Net-helper init : NAT traversal failed while creating socket\n");
217
		exit(1);
218
		break;
219
	case 2:
220
	    fprintf(stderr,"Net-helper init : NAT traversal timeout while creating socket\n");
221
	    fprintf(stderr,"Net-helper init : Retrying without STUN\n");
222
	    mlSetStunServer(0,NULL);
223
	    break;
224
	default :	// should never happen
225
		//
226
		fprintf(stderr,"Net-helper init : Unknown error in ml while creating socket\n");
227
	}
228

  
229
}
230

  
231
/**
232
 * Timeout callback to be set in the eventlib loop as needed
233
 * @param socket
234
 * @param flag
235
 * @param arg
236
 */
237
static void t_out_cb (int socket, short flag, void* arg) {
238

  
239
	timeoutFired = 1;
240
//	fprintf(stderr,"TIMEOUT!!!\n");
241
//	event_base_loopbreak(base);
242
}
243

  
244
/**
245
 * File descriptor readable callback to be set in the eventlib loop as needed
246
 */
247
static void fd_cb (int fd, short flag, void* arg)
248
{
249
  //fprintf(stderr, "\twait4data: fd %d triggered\n", fd);
250
  fdTriggered = true;
251
  *((bool*)arg) = true;
252
}
253

  
254
/**
255
 * Callback called by ml when a remote node ask for a connection
256
 * @param connectionID
257
 * @param arg
258
 */
259
static void receive_conn_cb(int connectionID, void *arg) {
260
//    fprintf(stderr, "Net-helper : remote peer opened the connection %d with arg = %d\n", connectionID,(int)arg);
261

  
262
}
263

  
264
void free_sending_buffer(int i)
265
{
266
	free(sendingBuffer[i]);
267
	sendingBuffer[i] = NULL;
268
}
269

  
270
/**
271
 * Callback called by the ml when a connection is ready to be used to send data to a remote peer
272
 * @param connectionID
273
 * @param arg
274
 */
275
static void connReady_cb (int connectionID, void *arg) {
276

  
277
	msgData_cb *p;
278
	p = (msgData_cb *)arg;
279
	if (p == NULL) return;
280
	if (p->cancelled) {
281
	    free(p);
282
	    return;
283
	}
284
	mlSendData(connectionID,(char *)(sendingBuffer[p->bIdx]),p->mSize,p->msgType,NULL);
285
	free_sending_buffer(p->bIdx);
286
//	fprintf(stderr,"Net-helper: Message # %d for connection %d sent!\n ", p->bIdx,connectionID);
287
	//	event_base_loopbreak(base);
288
	p->conn_cb_called = true;
289
}
290

  
291
/**
292
 * Callback called by ml when a connection error occurs
293
 * @param connectionID
294
 * @param arg
295
 */
296
static void connError_cb (int connectionID, void *arg) {
297
	// simply get rid of the msg in the buffer....
298
	msgData_cb *p;
299
	p = (msgData_cb *)arg;
300
	if (p != NULL) {
301
		fprintf(stderr,"Net-helper: Connection %d could not be established to send msg %d.\n ", connectionID,p->bIdx);
302
		if (p->cancelled) {
303
			free(p);//p->mSize = -1;
304
		} else {
305
			p->conn_cb_called = true;
306
		}
307
	}
308
	//	event_base_loopbreak(base);
309
}
310

  
311

  
312
/**
313
 * Callback to receive data from ml
314
 * @param buffer
315
 * @param buflen
316
 * @param msgtype
317
 * @param arg
318
 */
319
static void recv_data_cb(char *buffer, int buflen, unsigned char msgtype, recv_params *arg) {
320
// TODO: lacks a void* arg... moreover: recv_params has a msgtype, but there is also a msgtype explicit argument...
321
	char str[SOCKETID_STRING_SIZE];
322
//	fprintf(stderr, "Net-helper : called back with some news...\n");
323
/**/ ++recv_counter;
324
	if (arg->remote_socketID != NULL)
325
		mlSocketIDToString(arg->remote_socketID,str,SOCKETID_STRING_SIZE);
326
	else
327
		sprintf(str,"!Unknown!");
328
	if (arg->nrMissingBytes || !arg->firstPacketArrived) {
329
	    fprintf(stderr, "Net-helper : corrupted message arrived from %s\n",str);
330
	    fprintf(stderr, "\tMessage # %d -- Missing # %d bytes%s\n",
331
			recv_counter, arg->nrMissingBytes, arg->firstPacketArrived?"":", Missing first!");
332
	}
333
	else {
334
	//	fprintf(stderr, "Net-helper : message arrived from %s\n",str);
335
		// buffering the received message only if possible, otherwise ignore it...
336
		int index = next_R();
337
		if (index<0) {
338
			fprintf(stderr,"Net-helper: receive buffer full\n ");
339
			return;
340
		} else {
341
			receivedBuffer[index].data = malloc(buflen);
342
			if (receivedBuffer[index].data == NULL) {
343
				fprintf(stderr,"Net-helper: memory full, can't receive!\n ");
344
				return;
345
			}
346
			receivedBuffer[index].len = buflen;
347
			memcpy(receivedBuffer[index].data,buffer,buflen);
348
			  // save the socketID of the sender
349
			receivedBuffer[index].id = id_lookup_dup(arg->remote_socketID);
350
		}
351
  }
352
//	event_base_loopbreak(base);
353
}
354

  
355

  
356
struct nodeID *net_helper_init(const char *IPaddr, int port, const char *config) {
357

  
358
	struct timeval tout = NH_ML_INIT_TIMEOUT;
359
	int s, i;
360
	struct tag *cfg_tags;
361
	const char *res;
362
	const char *stun_server = "130.192.9.140";	//rucola.polito.it
363
	int stun_port = 3478;
364
	const char *repo_address = NULL;
365
	int publish_interval = 60;
366

  
367
	int verbosity = DCLOG_ERROR;
368

  
369
	int bucketsize = 80000; /* this allows a burst of 80000 Bytes [Bytes] */
370
	int rate = 10000000; /* 10Mbit/s [bits/s]*/
371
	int queuesize = 1000000; /* up to 1MB of data will be stored in the shaper transmission queue [Bytes]*/
372
	int RTXqueuesize = 1000000; /* up to 1 MB of data will be stored in the shaper retransmission queue [Bytes] */
373
	double RTXholtdingtime = 1.0; /* [seconds] */
374

  
375
#ifndef _WIN32
376
	signal(SIGPIPE, SIG_IGN); // workaround for a known issue in libevent2 with SIGPIPE on TPC connections
377
#endif
378
	base = event_base_new();
379
	lookup_array = calloc(lookup_max,sizeof(struct nodeID *));
380

  
381
	cfg_tags = config_parse(config);
382
	if (!cfg_tags) {
383
		return NULL;
384
	}
385

  
386
	res = config_value_str(cfg_tags, "stun_server");
387
	if (res) {
388
		stun_server = res;
389
	}
390
	config_value_int(cfg_tags, "stun_port", &stun_port);
391

  
392
	res = config_value_str(cfg_tags, "repo_address");
393
	if (res) {
394
		repo_address = res;
395
	}
396
	
397
	config_value_int(cfg_tags, "publish_interval", &publish_interval);
398

  
399
	config_value_int(cfg_tags, "verbosity", &verbosity);
400

  
401
	config_value_int(cfg_tags, "bucketsize", &bucketsize);
402
	config_value_int(cfg_tags, "rate", &rate);
403
	config_value_int(cfg_tags, "queuesize", &queuesize);
404
	config_value_int(cfg_tags, "RTXqueuesize", &RTXqueuesize);
405
	config_value_double(cfg_tags, "RTXholtdingtime", &RTXholtdingtime);
406

  
407
	me = malloc(sizeof(nodeID));
408
	if (me == NULL) {
409
		return NULL;
410
	}
411
	memset(me,0,sizeof(nodeID));
412
	me->connID = -10;	// dirty trick to spot later if the ml has called back ...
413
	me->refcnt = 1;
414

  
415
	for (i=0;i<NH_BUFFER_SIZE;i++) {
416
		sendingBuffer[i] = NULL;
417
		receivedBuffer[i].data = NULL;
418
	}
419

  
420
	mlRegisterErrorConnectionCb(&connError_cb);
421
	mlRegisterRecvConnectionCb(&receive_conn_cb);
422
	s = mlInit(1, tout, port, IPaddr, stun_port, stun_server, &init_myNodeID_cb, base);
423
	if (s < 0) {
424
		fprintf(stderr, "Net-helper : error initializing ML!\n");
425
		free(me);
426
		return NULL;
427
	}
428

  
429
	mlSetVerbosity(verbosity);
430

  
431
	mlSetRateLimiterParams(bucketsize, rate, queuesize, RTXqueuesize, RTXholtdingtime);
432

  
433
#ifdef MONL
434
{
435
	void *repoclient;
436
	eventbase = base;
437

  
438
	// Initialize logging
439
	napaInitLog(verbosity, NULL, NULL);
440

  
441
	repInit("");
442
	repoclient = repOpen(repo_address, publish_interval);	//repository.napa-wine.eu
443
	// NULL is inow valid for disabled repo 
444
	// if (repoclient == NULL) fatal("Unable to initialize repoclient");
445
	monInit(base, repoclient);
446
}
447
#endif
448
	free(cfg_tags);
449

  
450
	while (me->connID<-1) {
451
	//	event_base_once(base,-1, EV_TIMEOUT, &t_out_cb, NULL, &tout);
452
		event_base_loop(base,EVLOOP_ONCE);
453
	}
454
	timeoutFired = 0;
455
//	fprintf(stderr,"Net-helper init : back from init!\n");
456

  
457
	return me;
458
}
459

  
460

  
461
void bind_msg_type (unsigned char msgtype) {
462

  
463
			mlRegisterRecvDataCb(&recv_data_cb,msgtype);
464
}
465

  
466

  
467
void send_to_peer_cb(int fd, short event, void *arg)
468
{
469
	msgData_cb *p = (msgData_cb *) arg;
470
	if (p->conn_cb_called) {
471
		free(p);
472
	}
473
	else { //don't send it anymore
474
		free_sending_buffer(p->bIdx);
475
		p->cancelled = true;
476
		// don't free p, the other timeout will do it
477
	}
478
}
479

  
480
/**
481
 * Called by the application to send data to a remote peer
482
 * @param from
483
 * @param to
484
 * @param buffer_ptr
485
 * @param buffer_size
486
 * @return The dimension of the buffer or -1 if a connection error occurred.
487
 */
488
int send_to_peer(const struct nodeID *from, struct nodeID *to, const uint8_t *buffer_ptr, int buffer_size)
489
{
490
	msgData_cb *p;
491
	int current;
492
	send_params params = {0,0,0,0};
493

  
494
	if (buffer_size <= 0) {
495
		fprintf(stderr,"Net-helper: message size problematic: %d\n", buffer_size);
496
		return buffer_size;
497
	}
498

  
499
	// if buffer is full, discard the message and return an error flag
500
	int index = next_S();
501
	if (index<0) {
502
		// free(buffer_ptr);
503
		fprintf(stderr,"Net-helper: send buffer full\n ");
504
		return -1;
505
	}
506
	sendingBuffer[index] = malloc(buffer_size);
507
	if (! sendingBuffer[index]){
508
		fprintf(stderr,"Net-helper: memory full, can't send!\n ");
509
		return -1;
510
	}
511
	memset(sendingBuffer[index],0,buffer_size);
512
	memcpy(sendingBuffer[index],buffer_ptr,buffer_size);
513
	// free(buffer_ptr);
514
	p = malloc(sizeof(msgData_cb));
515
	p->bIdx = index; p->mSize = buffer_size; p->msgType = (unsigned char)buffer_ptr[0]; p->conn_cb_called = false; p->cancelled = false;
516
	current = p->bIdx;
517

  
518
	to->connID = mlOpenConnection(to->addr,&connReady_cb,p, params);
519
	if (to->connID<0) {
520
		free_sending_buffer(current);
521
		fprintf(stderr,"Net-helper: Couldn't get a connection ID to send msg %d.\n ", p->bIdx);
522
		free(p);
523
		return -1;
524
	}
525
	else {
526
		struct timeval timeout = NH_PACKET_TIMEOUT;
527
		event_base_once(base, -1, EV_TIMEOUT, send_to_peer_cb, (void *) p, &timeout);
528
		return buffer_size; //p->mSize;
529
	}
530

  
531
}
532

  
533

  
534
/**
535
 * Called by an application to receive data from remote peers
536
 * @param local
537
 * @param remote
538
 * @param buffer_ptr
539
 * @param buffer_size
540
 * @return The number of received bytes or -1 if some error occurred.
541
 */
542
int recv_from_peer(const struct nodeID *local, struct nodeID **remote, uint8_t *buffer_ptr, int buffer_size)
543
{
544
	int size;
545
	if (receivedBuffer[rIdxUp].data==NULL) {	//block till first message arrives
546
		wait4data(local, NULL, NULL);
547
	}
548

  
549
	assert(receivedBuffer[rIdxUp].data && receivedBuffer[rIdxUp].id);
550

  
551
	(*remote) = receivedBuffer[rIdxUp].id;
552
	// retrieve a msg from the buffer
553
	size = receivedBuffer[rIdxUp].len;
554
	if (size>buffer_size) {
555
		fprintf(stderr, "Net-helper : recv_from_peer: buffer too small (size:%d > buffer_size: %d)!\n",size,buffer_size);
556
		return -1;
557
	}
558
	memcpy(buffer_ptr, receivedBuffer[rIdxUp].data, size);
559
	free(receivedBuffer[rIdxUp].data);
560
	receivedBuffer[rIdxUp].data = NULL;
561
	receivedBuffer[rIdxUp].id = NULL;
562

  
563
	rIdxUp = (rIdxUp+1)%NH_BUFFER_SIZE;
564

  
565
//	fprintf(stderr, "Net-helper : I've got mail!!!\n");
566

  
567
	return size;
568
}
569

  
570

  
571
int wait4data(const struct nodeID *n, struct timeval *tout, int *fds) {
572

  
573
	struct event *timeout_ev = NULL;
574
	struct event *fd_ev[FDSSIZE];
575
	bool fd_triggered[FDSSIZE] = { false };
576
	int i;
577

  
578
//	fprintf(stderr,"Net-helper : Waiting for data to come...\n");
579
	if (tout) {	//if tout==NULL, loop wait infinitely
580
	  timeout_ev = event_new(base, -1, EV_TIMEOUT, &t_out_cb, NULL);
581
	  event_add(timeout_ev, tout);
582
	}
583
	for (i = 0; fds && fds[i] != -1; i ++) {
584
	  if (i >= FDSSIZE) {
585
	    fprintf(stderr, "Can't listen on more than %d file descriptors!\n", FDSSIZE);
586
	    break;
587
	  }
588
	  fd_ev[i] = event_new(base, fds[i], EV_READ, &fd_cb, &fd_triggered[i]);
589
	  event_add(fd_ev[i], NULL);
590
	}
591

  
592
	while(receivedBuffer[rIdxUp].data==NULL && timeoutFired==0 && fdTriggered==0) {
593
	//	event_base_dispatch(base);
594
		event_base_loop(base,EVLOOP_ONCE);
595
	}
596

  
597
	//delete one-time events
598
	if (timeout_ev) {
599
	  if (!timeoutFired) event_del(timeout_ev);
600
	  event_free(timeout_ev);
601
	}
602
	for (i = 0; fds && fds[i] != -1; i ++) {
603
	  if (! fd_triggered[i]) {
604
	    fds[i] = -2;
605
	    event_del(fd_ev[i]);
606
	  //} else {
607
	    //fprintf(stderr, "\twait4data: fd %d triggered\n", fds[i]);
608
	  }
609
	  event_free(fd_ev[i]);
610
	}
611

  
612
	if (fdTriggered) {
613
	  fdTriggered = false;
614
	  //fprintf(stderr, "\twait4data: fd event\n");
615
	  return 2;
616
	} else if (timeoutFired) {
617
	  timeoutFired = 0;
618
	  //fprintf(stderr, "\twait4data: timed out\n");
619
	  return 0;
620
	} else if (receivedBuffer[rIdxUp].data!=NULL) {
621
	  //fprintf(stderr, "\twait4data: ML receive\n");
622
	  return 1;
623
	} else {
624
	  fprintf(stderr, "BUG in wait4data\n");
625
	  exit(EXIT_FAILURE);
626
	}
627
}
628

  
629
socketID_handle getRemoteSocketID(const char *ip, int port) {
630
	char str[SOCKETID_STRING_SIZE];
631
	socketID_handle h;
632

  
633
	snprintf(str, SOCKETID_STRING_SIZE, "%s:%d-%s:%d", ip, port, ip, port);
634
	h = malloc(SOCKETID_SIZE);
635
	mlStringToSocketID(str, h);
636

  
637
	return h;
638
}
639

  
640
struct nodeID *create_node(const char *rem_IP, int rem_port) {
641
	socketID_handle s;
642
	struct nodeID *remote;
643

  
644
	s = getRemoteSocketID(rem_IP, rem_port);
645
	remote = id_lookup_dup(s);
646
	free(s);
647

  
648
	return remote;
649
}
650

  
651
int node_ip(const struct nodeID *s, char *ip, int size) {
652
	int len;
653
	const char *start, *end;
654
	char tmp[256];
655
	
656
	node_addr(s, tmp, 256);
657
 
658
	start = strstr(tmp, "-") + 1;
659
	end = strstr(start, ":");
660
	len = end - start;
661
	if (len >= size) {
662
		return -1;
663
	}
664
	memcpy(ip, start, len);
665
	ip[len] = 0;
666

  
667
	return 1;
668
}
669

  
670
// TODO: check why closing the connection is annoying for the ML
671
void nodeid_free(struct nodeID *n) {
672
	if (n && (--(n->refcnt) == 1)) {
673
/*
674
		struct nodeID **npos;
675
	//	mlCloseConnection(n->connID);
676
		npos = id_lookup(n->addr);
677
		*npos = NULL;
678
		mlCloseSocket(n->addr);
679
		free(n);
680
*/
681
	}
682
}
683

  
684

  
685
int node_addr(const struct nodeID *s, char *addr, int len)
686
{
687
  // TODO: mlSocketIDToString always return 0 !!!
688
  int r = mlSocketIDToString(s->addr,addr,len);
689
  if (!r)
690
	  return 1;
691
  else
692
	  return -1;
693
}
694

  
695
struct nodeID *nodeid_dup(struct nodeID *s)
696
{
697
	s->refcnt++;
698
	return s;
699
}
700

  
701
int nodeid_equal(const struct nodeID *s1, const struct nodeID *s2)
702
{
703
	return (mlCompareSocketIDs(s1->addr,s2->addr) == 0);
704
}
705

  
706
int nodeid_cmp(const struct nodeID *s1, const struct nodeID *s2)
707
{
708
	return mlCompareSocketIDs(s1->addr,s2->addr);
709
}
710

  
711
int nodeid_dump(uint8_t *b, const struct nodeID *s, size_t max_write_size)
712
{
713
  if (max_write_size < SOCKETID_STRING_SIZE) return -1;
714

  
715
  mlSocketIDToString(s->addr,(char *)b,SOCKETID_STRING_SIZE);
716
  //fprintf(stderr,"Dumping nodeID : ho scritto %s (%d bytes)\n",b, strlen((char *)b));
717

  
718
//	memcpy(b, s->addr,SOCKETID_SIZE);//sizeof(struct sockaddr_in6)*2
719
//	return SOCKETID_SIZE;//sizeof(struct sockaddr_in6)*2;
720

  
721
  return 1 + strlen((char *)b);	//terminating \0 IS included in the size
722
}
723

  
724
struct nodeID *nodeid_undump(const uint8_t *b, int *len)
725
{
726
  uint8_t sid[SOCKETID_SIZE];
727
  socketID_handle h = (socketID_handle) sid;
728
  mlStringToSocketID((char *)b,h);
729
  *len = strlen((char*)b) + 1;
730
  return id_lookup_dup(h);
731
}

Also available in: Unified diff