forked from RedisLabs/redisraft
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnode_addr.c
100 lines (85 loc) · 2.47 KB
/
node_addr.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/*
* This file is part of RedisRaft.
*
* Copyright (c) 2020-2021 Redis Ltd.
*
* RedisRaft is licensed under the Redis Source Available License (RSAL).
*/
#include <string.h>
#include <stdlib.h>
#include "redisraft.h"
/* Attempt to parse a node address in the form of <addr>:<port>
* and populate the result NodeAddr. Returns true if successful.
*/
bool NodeAddrParse(const char *node_addr, size_t node_addr_len, NodeAddr *result)
{
char buf[32] = { 0 };
char *endptr;
unsigned long l;
/* Split */
const char *colon = node_addr + node_addr_len;
while (colon > node_addr && *colon != ':') {
colon--;
}
if (*colon != ':') {
return false;
}
/* Get port */
int portlen = node_addr_len - (colon + 1 - node_addr);
if (portlen >= sizeof(buf) || portlen < 1) {
return false;
}
strncpy(buf, colon + 1, portlen);
l = strtoul(buf, &endptr, 10);
if (*endptr != '\0' || l < 1 || l > 65535) {
return false;
}
result->port = l;
/* Get addr */
int addrlen = colon - node_addr;
if (addrlen >= sizeof(result->host)) {
addrlen = sizeof(result->host)-1;
}
memcpy(result->host, node_addr, addrlen);
result->host[addrlen] = '\0';
return true;
}
/* Compare two NodeAddr structs */
bool NodeAddrEqual(const NodeAddr *a1, const NodeAddr *a2)
{
return (a1->port == a2->port && !strcmp(a1->host, a2->host));
}
/* Add a NodeAddrListElement to a chain of elements. If an existing element with the same
* address already exists, nothing is done. The addr pointer provided is copied into newly
* allocated memory, caller should free addr if necessary.
*/
void NodeAddrListAddElement(NodeAddrListElement **head, const NodeAddr *addr)
{
while (*head != NULL) {
if (NodeAddrEqual(&(*head)->addr, addr)) {
return;
}
head = &(*head)->next;
}
*head = RedisModule_Calloc(1, sizeof(NodeAddrListElement));
(*head)->addr = *addr;
}
/* Concat a NodeAddrList to another NodeAddrList */
void NodeAddrListConcat(NodeAddrListElement **head, const NodeAddrListElement *other)
{
const NodeAddrListElement *e = other;
while (e != NULL) {
NodeAddrListAddElement(head, &e->addr);
e = e->next;
}
}
/* Free a linked list of NodeAddrListElement */
void NodeAddrListFree(NodeAddrListElement *head)
{
NodeAddrListElement *t;
while (head != NULL) {
t = head->next;
RedisModule_Free(head);
head = t;
}
}