Statistics
| Branch: | Revision:

grapes / src / net_helper-ml.c @ bc246ff1

History | View | Annotate | Download (18.2 KB)

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 "grapes_log.h"
29
#include "repoclient.h"
30
#include "grapes.h"
31
#endif
32

    
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 int sIdx = 0;
47
static int rIdxML = 0;        //reveive from ML to this buffer position
48
static int rIdxUp = 0;        //hand up to layer above at this buffer position
49

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

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

    
71
static struct nodeID **lookup_array;
72
static int lookup_max = NH_LOOKUP_SIZE;
73
static int lookup_curr = 0;
74

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

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

    
90

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

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

    
110
        res->refcnt = 1;
111

    
112
        res->connID = mlOpenConnection(peer, &connReady_cb, NULL, params);
113

    
114
        return res;
115
}
116

    
117

    
118
static struct nodeID **id_lookup(socketID_handle target) {
119

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

    
131
        if (here == -1) {
132
                here = lookup_curr++;
133
        }
134

    
135
        if (lookup_curr > lookup_max) {
136
                lookup_max *= 2;
137
                lookup_array = realloc(lookup_array,lookup_max*sizeof(struct nodeID*));
138
        }
139

    
140
        lookup_array[here] = new_node(target);
141
        return &lookup_array[here];
142
}
143

    
144
static struct nodeID *id_lookup_dup(socketID_handle target) {
145
        return nodeid_dup(*id_lookup(target));
146
}
147

    
148

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

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

    
183

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

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

    
225
}
226

    
227
/**
228
 * Timeout callback to be set in the eventlib loop as needed
229
 * @param socket
230
 * @param flag
231
 * @param arg
232
 */
233
static void t_out_cb (int socket, short flag, void* arg) {
234

    
235
        timeoutFired = 1;
236
//        fprintf(stderr,"TIMEOUT!!!\n");
237
//        event_base_loopbreak(base);
238
}
239

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

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

    
258
}
259

    
260
void free_sending_buffer(int i)
261
{
262
        free(sendingBuffer[i]);
263
        sendingBuffer[i] = NULL;
264
}
265

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

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

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

    
307

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

    
351

    
352
struct nodeID *net_helper_init(const char *IPaddr, int port, const char *config) {
353

    
354
        struct timeval tout = NH_ML_INIT_TIMEOUT;
355
        int s, i;
356
        struct tag *cfg_tags;
357
        const char *res;
358
        const char *stun_server = "stun.ekiga.net";
359
        int stun_port = 3478;
360
        const char *repo_address = NULL;
361
        int publish_interval = 60;
362

    
363
        int verbosity = DCLOG_ERROR;
364

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

    
371
#ifndef WIN32
372
        signal(SIGPIPE, SIG_IGN); // workaround for a known issue in libevent2 with SIGPIPE on TPC connections
373
#endif
374
        base = event_base_new();
375
        lookup_array = calloc(lookup_max,sizeof(struct nodeID *));
376

    
377
        cfg_tags = config_parse(config);
378
        if (!cfg_tags) {
379
                return NULL;
380
        }
381

    
382
        res = config_value_str(cfg_tags, "stun_server");
383
        if (res) {
384
                stun_server = res;
385
        }
386
        config_value_int(cfg_tags, "stun_port", &stun_port);
387

    
388
        res = config_value_str(cfg_tags, "repo_address");
389
        if (res) {
390
                repo_address = res;
391
        }
392
        
393
        config_value_int(cfg_tags, "publish_interval", &publish_interval);
394

    
395
        config_value_int(cfg_tags, "verbosity", &verbosity);
396

    
397
        config_value_int(cfg_tags, "bucketsize", &bucketsize);
398
        config_value_int(cfg_tags, "rate", &rate);
399
        config_value_int(cfg_tags, "queuesize", &queuesize);
400
        config_value_int(cfg_tags, "RTXqueuesize", &RTXqueuesize);
401
        config_value_double(cfg_tags, "RTXholtdingtime", &RTXholtdingtime);
402

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

    
411
        for (i=0;i<NH_BUFFER_SIZE;i++) {
412
                sendingBuffer[i] = NULL;
413
                receivedBuffer[i].data = NULL;
414
        }
415

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

    
425
        mlSetVerbosity(verbosity);
426

    
427
        mlSetRateLimiterParams(bucketsize, rate, queuesize, RTXqueuesize, RTXholtdingtime);
428

    
429
#ifdef MONL
430
{
431
        void *repoclient;
432
        eventbase = base;
433

    
434
        // Initialize logging
435
        grapesInitLog(verbosity, NULL, NULL);
436

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

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

    
453
        return me;
454
}
455

    
456

    
457
void bind_msg_type (unsigned char msgtype) {
458

    
459
                        mlRegisterRecvDataCb(&recv_data_cb,msgtype);
460
}
461

    
462

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

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

    
490
        if (buffer_size <= 0) {
491
                fprintf(stderr,"Net-helper: message size problematic: %d\n", buffer_size);
492
                return buffer_size;
493
        }
494

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

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

    
527
}
528

    
529

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

    
545
        assert(receivedBuffer[rIdxUp].data && receivedBuffer[rIdxUp].id);
546

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

    
559
        rIdxUp = (rIdxUp+1)%NH_BUFFER_SIZE;
560

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

    
563
        return size;
564
}
565

    
566

    
567
int wait4data(const struct nodeID *n, struct timeval *tout, int *fds) {
568

    
569
        struct event *timeout_ev = NULL;
570
        struct event *fd_ev[FDSSIZE];
571
        bool fd_triggered[FDSSIZE] = { false };
572
        int i;
573

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

    
588
        while(receivedBuffer[rIdxUp].data==NULL && timeoutFired==0 && fdTriggered==0) {
589
        //        event_base_dispatch(base);
590
                event_base_loop(base,EVLOOP_ONCE);
591
        }
592

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

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

    
625
socketID_handle getRemoteSocketID(const char *ip, int port) {
626
        char str[SOCKETID_STRING_SIZE];
627
        socketID_handle h;
628

    
629
        snprintf(str, SOCKETID_STRING_SIZE, "%s:%d-%s:%d", ip, port, ip, port);
630
        h = malloc(SOCKETID_SIZE);
631
        mlStringToSocketID(str, h);
632

    
633
        return h;
634
}
635

    
636
struct nodeID *create_node(const char *rem_IP, int rem_port) {
637
        socketID_handle s;
638
        struct nodeID *remote;
639

    
640
        s = getRemoteSocketID(rem_IP, rem_port);
641
        remote = id_lookup_dup(s);
642
        free(s);
643

    
644
        return remote;
645
}
646

    
647
const char *node_ip(const struct nodeID *s) {
648
        static char ip[64];
649
        int len;
650
        const char *start, *end;
651
        const char *tmp = node_addr(s);
652
        start = strstr(tmp, "-") + 1;
653
        end = strstr(start, ":");
654
        len = end - start;
655
        memcpy(ip, start, len);
656
        ip[len] = 0;
657

    
658
        return (const char *)ip;
659
}
660

    
661
// TODO: check why closing the connection is annoying for the ML
662
void nodeid_free(struct nodeID *n) {
663
        if (n && (--(n->refcnt) == 1)) {
664
/*
665
                struct nodeID **npos;
666
        //        mlCloseConnection(n->connID);
667
                npos = id_lookup(n->addr);
668
                *npos = NULL;
669
                mlCloseSocket(n->addr);
670
                free(n);
671
*/
672
        }
673
}
674

    
675

    
676
const char *node_addr(const struct nodeID *s)
677
{
678
  static char addr[256];
679
  // TODO: mlSocketIDToString always return 0 !!!
680
  int r = mlSocketIDToString(s->addr,addr,256);
681
  if (!r)
682
          return addr;
683
  else
684
          return "";
685
}
686

    
687
struct nodeID *nodeid_dup(struct nodeID *s)
688
{
689
        s->refcnt++;
690
        return s;
691
}
692

    
693
int nodeid_equal(const struct nodeID *s1, const struct nodeID *s2)
694
{
695
        return (mlCompareSocketIDs(s1->addr,s2->addr) == 0);
696
}
697

    
698
int nodeid_dump(uint8_t *b, const struct nodeID *s, size_t max_write_size)
699
{
700
  if (max_write_size < SOCKETID_STRING_SIZE) return -1;
701

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

    
705
//        memcpy(b, s->addr,SOCKETID_SIZE);//sizeof(struct sockaddr_in6)*2
706
//        return SOCKETID_SIZE;//sizeof(struct sockaddr_in6)*2;
707

    
708
  return 1 + strlen((char *)b);        //terminating \0 IS included in the size
709
}
710

    
711
struct nodeID *nodeid_undump(const uint8_t *b, int *len)
712
{
713
  uint8_t sid[SOCKETID_SIZE];
714
  socketID_handle h = (socketID_handle) sid;
715
  mlStringToSocketID((char *)b,h);
716
  *len = strlen((char*)b) + 1;
717
  return id_lookup_dup(h);
718
}