-
Notifications
You must be signed in to change notification settings - Fork 0
/
SubnetStruct.h
131 lines (121 loc) · 4.24 KB
/
SubnetStruct.h
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/**
* Subnet Header
* =============
*
* This header contains the C functions needed for Protocol object in the p2p.today project.
*
* It automatically includes :doc:`BaseConverter.h <./BaseConverter>`
*
* Using this requires a compiled copy of the sha2 hashes, provided in ``c_src/sha/sha2.c``
*/
#include <string.h>
#include "./sha/sha2.h"
#include "./BaseConverter.h"
#ifdef _cplusplus
extern "C" {
#endif
typedef struct {
/**
* .. c:type:: typedef struct SubnetStruct
*
* .. c:member:: char *subnet
*
* The name of the desired subnet
*
* .. c:member:: size_t subnetSize
*
* The length of the desired subnet
*
* .. c:member:: char *encryption
*
* The desired transport method
*
* .. c:member:: size_t encryptionSize
*
* The length of the transport method
*
* .. c:member:: char *_id
*
* Private field which contains the hash ID of this network
*
* Use :c:func:`subnetID` to safely obtain this value. It is
* is allocated and calculated on demand only.
*
* .. c:member:: size_t *_id
*
* The length of this network's hash ID
*/
char *subnet, *encryption, *_id;
size_t subnetSize, encryptionSize, idSize;
} SubnetStruct;
static SubnetStruct *getSubnet(const char *subnet, size_t subnetSize, const char *encryption, size_t encryptionSize) {
/**
* .. c:function:: static SubnetStruct *getSubnet(const char *subnet, size_t subnetSize, const char *encryption, size_t encryptionSize)
*
* Constructs an SubnetStruct. This copies all given data into a struct, then returns this struct's pointer.
*
* :param subnet: The item to place in :c:member:`SubnetStruct.subnet`
* :param subnetSize: The length of the above
* :param encryption: The item to place in :c:member:`SubnetStruct.encryption`
* :param encryptionSize: The length of the above
*
* :returns: A pointer to the resulting :c:type:`SubnetStruct`
*
* .. warning::
*
* You must use :c:func:`destroySubnet` on the resulting object, or you will develop a memory leak
*/
SubnetStruct *ret = (SubnetStruct *) malloc(sizeof(SubnetStruct));
ret->subnetSize = subnetSize;
ret->encryptionSize = encryptionSize;
ret->subnet = (char *) malloc(sizeof(char) * subnetSize);
memcpy(ret->subnet, subnet, subnetSize);
ret->encryption = (char *) malloc(sizeof(char) * encryptionSize);
memcpy(ret->encryption, encryption, encryptionSize);
ret->_id = NULL;
ret->idSize = 0;
return ret;
}
static void destroySubnet(SubnetStruct *sub) {
/**
* .. c:function:: static void destroySubnet(SubnetStruct *des)
*
* :c:func:`free` an :c:type:`SubnetStruct` and its members
*
* :param des: A pointer to the SubnetStruct you wish to destroy
*/
free(sub->subnet);
free(sub->encryption);
if (sub->_id != NULL)
free(sub->_id);
free(sub);
}
static char *subnetID(SubnetStruct *sub) {
/**
* .. c:function:: static char *subnetID(SubnetStruct *sub)
*
* Ensures that a :c:type:`SubnetStruct` has an ID, and returns this ID.
*
* :returns: The given :c:type:`SubnetStruct`'s ID
*/
if (sub->_id == NULL) {
char buffer[6];
unsigned char digest[SHA256_DIGEST_LENGTH];
SHA256_CTX ctx;
size_t buffSize = sprintf(buffer, "%llu.%llu", (unsigned long long)C2P_PROTOCOL_MAJOR_VERSION, (unsigned long long)C2P_PROTOCOL_MINOR_VERSION);
size_t infoSize = buffSize + sub->subnetSize + sub->encryptionSize;
char *info = (char *) malloc(sizeof(char) * infoSize);
memcpy(info, sub->subnet, sub->subnetSize);
memcpy(info + sub->subnetSize, sub->encryption, sub->encryptionSize);
memcpy(info + sub->subnetSize + sub->encryptionSize, buffer, buffSize);
memset(digest, 0, SHA256_DIGEST_LENGTH);
SHA256_Init(&ctx);
SHA256_Update(&ctx, (unsigned char*)info, infoSize);
SHA256_Final(digest, &ctx);
sub->_id = ascii_to_base_58((char *)digest, SHA256_DIGEST_LENGTH, &(sub->idSize), 1);
}
return sub->_id;
}
#ifdef _cplusplus
}
#endif