Compare commits
1 commit
Author | SHA1 | Date | |
---|---|---|---|
|
0705909f4c |
27 changed files with 741 additions and 2528 deletions
78
.cproject
78
.cproject
|
@ -1,78 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
<cconfiguration id="cdt.managedbuild.toolchain.gnu.base.663343487">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.base.663343487" moduleId="org.eclipse.cdt.core.settings" name="Default">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration buildProperties="" id="cdt.managedbuild.toolchain.gnu.base.663343487" name="Default" parent="org.eclipse.cdt.build.core.emptycfg">
|
||||
<folderInfo id="cdt.managedbuild.toolchain.gnu.base.663343487.1554761701" name="/" resourcePath="">
|
||||
<toolChain id="cdt.managedbuild.toolchain.gnu.base.1976366028" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.base">
|
||||
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.GNU_ELF" id="cdt.managedbuild.target.gnu.platform.base.790917044" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
|
||||
<builder id="cdt.managedbuild.target.gnu.builder.base.667198033" managedBuildOn="false" name="Gnu Make Builder.Default" superClass="cdt.managedbuild.target.gnu.builder.base"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.archiver.base.1340147019" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.1587295855" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.compiler.base.548918774" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base">
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1621016424" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.linker.base.298540641" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base">
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.1326462310" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
</inputType>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.107597551" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.assembler.base.1765741010" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base">
|
||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1331876933" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||
</tool>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<project id="c-multiaddr.null.2082036538" name="c-multiaddr"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
<storageModule moduleId="refreshScope"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
|
||||
<buildTargets>
|
||||
<target name="all" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildTarget>all</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="clean" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildTarget>clean</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="rebuild" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>rebuild</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
</buildTargets>
|
||||
</storageModule>
|
||||
</cproject>
|
11
.gitignore
vendored
11
.gitignore
vendored
|
@ -1,11 +0,0 @@
|
|||
*
|
||||
|
||||
!.gitignore
|
||||
!Makefile
|
||||
!**/
|
||||
|
||||
*.o
|
||||
*.a
|
||||
.settings/language.settings.xml
|
||||
test_multiaddr
|
||||
|
26
.project
26
.project
|
@ -1,26 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>c-multiaddr</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<triggers>clean,full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
24
LICENSE
24
LICENSE
|
@ -1,24 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2019 AGORISE, LTD.
|
||||
An International Business Company, Cyprus Reg# ΗΕ375959
|
||||
|
||||
Contains works from BitShares Munich IVS
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
33
Makefile
33
Makefile
|
@ -1,33 +0,0 @@
|
|||
CC = gcc
|
||||
CFLAGS = -O0 -I include -std=c99
|
||||
|
||||
DEBUG = true
|
||||
|
||||
|
||||
ifdef DEBUG
|
||||
CFLAGS += -g3
|
||||
endif
|
||||
|
||||
LFLAGS = -lm
|
||||
DEPS = include/multiaddr/base58.h include/multiaddr/endian.h include/multiaddr/multiaddr.h \
|
||||
include/multiaddr/protocols.h include/multiaddr/protoutils.h include/multiaddr/varhexutils.h \
|
||||
include/multiaddr/varint.h
|
||||
OBJS = base58.o varint.o varhexutils.o protoutils.o protocols.o multiaddr.o
|
||||
|
||||
%.o: %.c $(DEPS)
|
||||
$(CC) -c -o $@ $< $(CFLAGS)
|
||||
|
||||
libmultiaddr.a: $(OBJS)
|
||||
ar rcs $@ $^
|
||||
|
||||
test_multiaddr: testing.o libmultiaddr.a
|
||||
$(CC) -o $@ $^ $(LFLAGS)
|
||||
|
||||
all: test_multiaddr
|
||||
|
||||
clean:
|
||||
rm -f *.o
|
||||
rm -f libmultiaddr.a
|
||||
rm -f test_multiaddr
|
||||
|
||||
rebuild: clean all
|
32
README.md
32
README.md
|
@ -1,34 +1,2 @@
|
|||
# c-multiaddr
|
||||
multiaddr for IPFS in C.
|
||||
|
||||
### Multiaddr provides easy networking protocols nesting, easy encapsulation of extra protocols, easy tunneling, etc.
|
||||
# Usage:
|
||||
#### All you need to include is multiaddr.h
|
||||
## Maddr struct:
|
||||
* char * string; // String that contains addresses such as /ip4/192.168.1.1/
|
||||
* uint8_t * bytes; // uint8_t * that contains the enecoded address
|
||||
* size_t bsize; //size_t that contains the real bytes size (Use it whenever using the bytes so you don't input trash!)
|
||||
|
||||
## New Multi Address From String(multiaddress_new_from_string)
|
||||
struct MultiAddress* a = multiaddress_new_from_string("/ip4/127.0.0.1/tcp/8080/");
|
||||
## Obtaining the byte buffer(.bytes, .bsize[0]):
|
||||
printf("TEST BYTES: %s\n",Var_To_Hex(a->bsize, a->bytes));
|
||||
Var_To_Hex = Byte Buffer to Hex String
|
||||
Hex_To_Var = Hex String to Byte Buffer
|
||||
## Encapsulation & Decapsulation(m_encapsulate, m_decapsulate)
|
||||
#### Remember, Decapsulation happens from right to left, never in reverse, if you have /ip4/udp/ipfs/ if you decapsulate "udp" you will also take out ipfs!
|
||||
* Now the string is: /ip4/192.168.1.1/
|
||||
* multiaddress_encapsulate(a,"/udp/3333/"); //Adds udp/3333/
|
||||
* Now the string is: /ip4/192.168.1.1/udp/3333/
|
||||
* multiaddress_decapsulate(a,"udp"); //Removes udp protocol and its address
|
||||
* Now the string is: /ip4/192.168.1.1/
|
||||
* multiaddress_encapsulate(a,"/tcp/8080");
|
||||
* Now the string is: /ip4/192.168.1.1/tcp/8080/
|
||||
|
||||
# Constructing a multiaddress from bytes:
|
||||
|
||||
* struct MultiAddress* beta;
|
||||
* beta = multiaddress_new_from_bytes(a->bytes,a->bsize); //This will already construct back to the string too!
|
||||
* printf("B STRING: %s\n",beta->string); //So after encapsulation and decapsulation atm this string would
|
||||
* contain: /ip4/192.168.1.1/tcp/8080/
|
||||
|
||||
|
|
21
STATUS
Normal file
21
STATUS
Normal file
|
@ -0,0 +1,21 @@
|
|||
STATUS:
|
||||
Compatibility: Windows/Mac/Linux/Openbsd based systems (probably more)
|
||||
-Finished Base58.h Encryption/Decryption Algorhytm
|
||||
-Finished Endian.h Library for automating compiling for Linux/Mac/Windows
|
||||
-Finished Varhexutils - Different conversion algorhytms between bytes and strings etc.
|
||||
-Finsihed Varint.h - Conversion from Hex
|
||||
-Finished Protocols.h - Library for loading protocols & manipulating them easily.
|
||||
What needs to be done (known so far):
|
||||
|
||||
-Not finished: protoutils.h (performs final byte encodings and checks for validity
|
||||
|
||||
-Not started: Multiaddr.h
|
||||
(The actual thing that makes everything simple, encapsulating different protocols easily for lower
|
||||
internet consumption and higher overall efficiency.) (Basically simulating classes from other languages for easy development)
|
||||
|
||||
Other things to do:
|
||||
Add conversion for bigendian machines (doubt anyone will actually need them tbh but portability was requested.)
|
||||
Should work on all platforms so far.
|
||||
Add proper documentation in case anyone needs to add protocols etc.
|
||||
|
||||
So far it's almost finished.
|
15
STATUS.md
15
STATUS.md
|
@ -1,15 +0,0 @@
|
|||
# STATUS:
|
||||
* Compatibility: Windows/Mac/Linux/Openbsd based systems (probably more)
|
||||
* Finished Base58.h Encryption/Decryption Algorhytm
|
||||
* Finished Endian.h Library for automating compiling for Linux/Mac/Windows
|
||||
* Finished Varhexutils - Different conversion algorhytms between bytes and strings etc.
|
||||
* Finsihed Varint.h - Conversion from Hex
|
||||
* Finished Protocols.h - Library for loading protocols & manipulating them easily.
|
||||
* Finished: Multiaddr.h (easy library for developers)
|
||||
* Finished: Protoutils.h Converting from string to hex/binary, analizing strings/bin for validity,parsing ipv4,etc.
|
||||
* Finished: Readme - Documentation on how to use everything so any new developer can easily use all of this
|
||||
# Secondary things that might need to be implemented:
|
||||
* Protocols, everything except IP4,TCP,UDP,IPFS - These we actually need.
|
||||
* Few issues that are not urgent:
|
||||
- Decapsulation of tunneled protocols doesn't work, this will be fixed if needed in multiaddr.h/m_decapsulate
|
||||
- Endianness Check - protoutils.h/in protocols UDP,TCP
|
200
base58.c
200
base58.c
|
@ -1,200 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-2014 Luke Dashjr
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the standard MIT license. See COPYING for more details.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
static const char b58digits_ordered[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||
|
||||
static const int8_t b58digits_map[] = {
|
||||
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8,-1,-1,-1,-1,-1,-1,
|
||||
-1, 9,10,11,12,13,14,15, 16,-1,17,18,19,20,21,-1,
|
||||
22,23,24,25,26,27,28,29, 30,31,32,-1,-1,-1,-1,-1,
|
||||
-1,33,34,35,36,37,38,39, 40,41,42,43,-1,44,45,46,
|
||||
47,48,49,50,51,52,53,54, 55,56,57,-1,-1,-1,-1,-1,
|
||||
};
|
||||
|
||||
/**
|
||||
* convert a base58 encoded string into a binary array
|
||||
* @param b58 the base58 encoded string
|
||||
* @param base58_size the size of the encoded string
|
||||
* @param bin the results buffer
|
||||
* @param binszp the size of the results buffer
|
||||
* @returns true(1) on success
|
||||
*/
|
||||
int multiaddr_encoding_base58_decode(const char* b58, size_t base58_size, unsigned char** bin, size_t* binszp)
|
||||
{
|
||||
size_t binsz = *binszp;
|
||||
const unsigned char* b58u = (const void*)b58;
|
||||
unsigned char* binu = *bin;
|
||||
size_t outisz = (binsz + 3) / 4;
|
||||
uint32_t outi[outisz];
|
||||
uint64_t t;
|
||||
uint32_t c;
|
||||
size_t i, j;
|
||||
uint8_t bytesleft = binsz % 4;
|
||||
uint32_t zeromask = bytesleft ? (0xffffffff << (bytesleft * 8)) : 0;
|
||||
unsigned zerocount = 0;
|
||||
size_t b58sz;
|
||||
|
||||
b58sz = strlen(b58);
|
||||
|
||||
memset(outi, 0, outisz * sizeof(*outi));
|
||||
|
||||
// Leading zeros, just count
|
||||
for (i = 0; i < b58sz && !b58digits_map[b58u[i]]; ++i) {
|
||||
++zerocount;
|
||||
}
|
||||
|
||||
for (; i < b58sz; ++i) {
|
||||
if (b58u[i] & 0x80) {
|
||||
// High-bit set on invalid digit
|
||||
return 0;
|
||||
}
|
||||
if (b58digits_map[b58u[i]] == -1) {
|
||||
// Invalid base58 digit
|
||||
return 0;
|
||||
}
|
||||
c = (unsigned)b58digits_map[b58u[i]];
|
||||
for (j = outisz; j--;) {
|
||||
t = ((uint64_t)outi[j]) * 58 + c;
|
||||
c = (t & 0x3f00000000) >> 32;
|
||||
outi[j] = t & 0xffffffff;
|
||||
}
|
||||
if (c) {
|
||||
// Output number too big (carry to the next int32)
|
||||
memset(outi, 0, outisz * sizeof(*outi));
|
||||
return 0;
|
||||
}
|
||||
if (outi[0] & zeromask) {
|
||||
// Output number too big (last int32 filled too far)
|
||||
memset(outi, 0, outisz * sizeof(*outi));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
j = 0;
|
||||
switch (bytesleft) {
|
||||
case 3:
|
||||
*(binu++) = (outi[0] & 0xff0000) >> 16;
|
||||
case 2:
|
||||
*(binu++) = (outi[0] & 0xff00) >> 8;
|
||||
case 1:
|
||||
*(binu++) = (outi[0] & 0xff);
|
||||
++j;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (; j < outisz; ++j) {
|
||||
*(binu++) = (outi[j] >> 0x18) & 0xff;
|
||||
*(binu++) = (outi[j] >> 0x10) & 0xff;
|
||||
*(binu++) = (outi[j] >> 8) & 0xff;
|
||||
*(binu++) = (outi[j] >> 0) & 0xff;
|
||||
}
|
||||
|
||||
// Count canonical base58 byte count
|
||||
binu = *bin;
|
||||
for (i = 0; i < binsz; ++i) {
|
||||
if (binu[i]) {
|
||||
break;
|
||||
}
|
||||
--*binszp;
|
||||
}
|
||||
*binszp += zerocount;
|
||||
|
||||
memset(outi, 0, outisz * sizeof(*outi));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* encode an array of bytes into a base58 string
|
||||
* @param binary_data the data to be encoded
|
||||
* @param binary_data_size the size of the data to be encoded
|
||||
* @param base58 the results buffer
|
||||
* @param base58_size the size of the results buffer
|
||||
* @returns true(1) on success
|
||||
*/
|
||||
int multiaddr_encoding_base58_encode(const unsigned char* data, size_t binsz, unsigned char** b58, size_t* b58sz)
|
||||
{
|
||||
const uint8_t* bin = data;
|
||||
int carry;
|
||||
ssize_t i, j, high, zcount = 0;
|
||||
size_t size;
|
||||
|
||||
while (zcount < (ssize_t)binsz && !bin[zcount]) {
|
||||
++zcount;
|
||||
}
|
||||
|
||||
size = (binsz - zcount) * 138 / 100 + 1;
|
||||
uint8_t buf[size];
|
||||
memset(buf, 0, size);
|
||||
|
||||
for (i = zcount, high = size - 1; i < (ssize_t)binsz; ++i, high = j) {
|
||||
for (carry = bin[i], j = size - 1; (j > high) || carry; --j) {
|
||||
carry += 256 * buf[j];
|
||||
buf[j] = carry % 58;
|
||||
carry /= 58;
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < (ssize_t)size && !buf[j]; ++j)
|
||||
;
|
||||
|
||||
if (*b58sz <= zcount + size - j) {
|
||||
*b58sz = zcount + size - j + 1;
|
||||
memset(buf, 0, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (zcount) {
|
||||
memset(b58, '1', zcount);
|
||||
}
|
||||
for (i = zcount; j < (ssize_t)size; ++i, ++j) {
|
||||
(*b58)[i] = b58digits_ordered[buf[j]];
|
||||
}
|
||||
(*b58)[i] = '\0';
|
||||
*b58sz = i + 1;
|
||||
|
||||
memset(buf, 0, size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/***
|
||||
* calculate the size of the binary results based on an incoming base58 string
|
||||
* @param base58_string the string
|
||||
* @returns the size in bytes had the string been decoded
|
||||
*/
|
||||
size_t multiaddr_encoding_base58_decode_size(const unsigned char* base58_string) {
|
||||
size_t string_length = strlen((char*)base58_string);
|
||||
size_t decoded_length = 0;
|
||||
size_t radix = strlen(b58digits_ordered);
|
||||
double bits_per_digit = log2(radix);
|
||||
|
||||
decoded_length = floor(string_length * bits_per_digit / 8);
|
||||
return decoded_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* calculate the max length in bytes of an encoding of n source bits
|
||||
* @param base58_string the string
|
||||
* @returns the maximum size in bytes had the string been decoded
|
||||
*/
|
||||
size_t multiaddr_encoding_base58_decode_max_size(const unsigned char* base58_string) {
|
||||
size_t string_length = strlen((char*)base58_string);
|
||||
size_t decoded_length = 0;
|
||||
size_t radix = strlen(b58digits_ordered);
|
||||
double bits_per_digit = log2(radix);
|
||||
|
||||
decoded_length = ceil(string_length * bits_per_digit / 8);
|
||||
return decoded_length;
|
||||
}
|
104
base58.h
Normal file
104
base58.h
Normal file
|
@ -0,0 +1,104 @@
|
|||
#ifndef __BASE58_H__
|
||||
#define __BASE58_H__
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#define BASE58_DECODE_BASE 0
|
||||
#define BASE58_ENCODE_BASE 0
|
||||
#define BASE58_DECODE_OUT_OF_RANGE 1
|
||||
|
||||
void print_array(unsigned char* arr, int len){
|
||||
int i = 0;
|
||||
for (i=0; i<len; ++i){
|
||||
printf("%02X ",arr[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static unsigned char alphabet[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||
|
||||
int base58Encode(const char* input,const unsigned int inLen,unsigned char *output,unsigned int outLen)
|
||||
{
|
||||
int i,j,tmp;
|
||||
memset(output,0,outLen);
|
||||
for(i=0;i<inLen;i++)
|
||||
{
|
||||
unsigned int c = input[i] & (0xff) ;
|
||||
for(j=outLen-1;j>=0;j--)
|
||||
{
|
||||
tmp = output[j] * 256 + c;
|
||||
c = tmp/58;
|
||||
output[j] = tmp%58;
|
||||
}
|
||||
}
|
||||
for(j=0; j<outLen; ++j)
|
||||
{
|
||||
output[j] = alphabet[output[j]];
|
||||
}
|
||||
return BASE58_ENCODE_BASE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int base58Decode(const char* addr,const unsigned int addrLen,unsigned char *buf,unsigned int bufLen)
|
||||
{
|
||||
int i,j;
|
||||
unsigned int tmp;
|
||||
memset(buf,0,bufLen);
|
||||
for(i=0;i<addrLen;i++)
|
||||
{
|
||||
unsigned int c = addr[i];
|
||||
|
||||
if (addr[i] < 58){ // Numbers
|
||||
c -= 49;
|
||||
}else if (addr[i] < 73){ // A-H
|
||||
c -= 56;
|
||||
}else if (addr[i] < 79){ // J-N
|
||||
c -= 57;
|
||||
}else if (addr[i] < 91){ // P-Z
|
||||
c -= 58;
|
||||
}else if (addr[i] < 108){ // a-k
|
||||
c -= 64;
|
||||
}else{ // m-z
|
||||
c -= 65;
|
||||
}
|
||||
|
||||
for(j=bufLen-1;j>=0;j--)
|
||||
{
|
||||
tmp = buf[j] * 58 + c;
|
||||
c = (tmp & (~0xff)) >> 8;
|
||||
buf[j] = tmp & (0xff);
|
||||
}
|
||||
}
|
||||
|
||||
return BASE58_DECODE_BASE;
|
||||
}
|
||||
#endif
|
||||
/*int main()
|
||||
{
|
||||
//char addr[]="1NQEQ7fkCQQiVKDohBGuE3zSYs7xfDobbg";
|
||||
char addr[]="Qmaa4Rw81a3a1VEx4LxB7HADUAXvZFhCoRdBzsMZyZmqHD";
|
||||
|
||||
//char addr[]="5R1";
|
||||
//char addr[]="113YAvwi1V9WV9GEykK6XQ1UypmFPhVyh1";
|
||||
const int addrLen = sizeof(addr)-1;
|
||||
//char addr[]="115R";
|
||||
//const int addrLen = 4;
|
||||
const int bufLen = 40;
|
||||
char buf[bufLen];
|
||||
char addr2[addrLen];
|
||||
memset(buf,0,bufLen);
|
||||
printf("%s in Array[i] \BYTES AS HEX:", addr);
|
||||
print_array(addr,addrLen);
|
||||
printf("DECODED:");
|
||||
base58Decode(addr, addrLen, buf, bufLen);
|
||||
print_array(buf,bufLen);
|
||||
|
||||
printf("ENCODED:");
|
||||
base58Encode(buf, bufLen, addr2, addrLen);
|
||||
print_array(addr2,addrLen);
|
||||
|
||||
return 0;
|
||||
}*/
|
|
@ -1,39 +0,0 @@
|
|||
#ifndef base58_h
|
||||
#define base58_h
|
||||
#include "varint.h"
|
||||
/**
|
||||
* convert a base58 encoded string into a binary array
|
||||
* @param base58 the base58 encoded string
|
||||
* @param base58_size the size of the encoded string
|
||||
* @param binary_data the results buffer
|
||||
* @param binary_data_size the size of the results buffer
|
||||
* @returns true(1) on success
|
||||
*/
|
||||
int multiaddr_encoding_base58_decode(const char* base58, size_t base58_size, unsigned char** binary_data, size_t *binary_data_size);
|
||||
|
||||
/**
|
||||
* encode an array of bytes into a base58 string
|
||||
* @param binary_data the data to be encoded
|
||||
* @param binary_data_size the size of the data to be encoded
|
||||
* @param base58 the results buffer
|
||||
* @param base58_size the size of the results buffer
|
||||
* @returns true(1) on success
|
||||
*/
|
||||
int multiaddr_encoding_base58_encode(const unsigned char* binary_data, size_t binary_data_size, unsigned char** base58, size_t* base58_size);
|
||||
|
||||
/***
|
||||
* calculate the size of the binary results based on an incoming base58 string with no initial padding
|
||||
* @param base58_string the string
|
||||
* @returns the size in bytes had the string been decoded
|
||||
*/
|
||||
size_t multiaddr_encoding_base58_decode_size(const unsigned char* base58_string);
|
||||
|
||||
/**
|
||||
* calculate the max length in bytes of an encoding of n source bits
|
||||
* @param base58_string the string
|
||||
* @returns the maximum size in bytes had the string been decoded
|
||||
*/
|
||||
size_t multiaddr_encoding_base58_decode_max_size(const unsigned char* base58_string);
|
||||
|
||||
|
||||
#endif /* base58_h */
|
|
@ -1,106 +0,0 @@
|
|||
#ifndef MULTIADDR
|
||||
#define MULTIADDR
|
||||
#include <string.h>
|
||||
|
||||
#include "varhexutils.h"
|
||||
#include "varint.h"
|
||||
#include "protocols.h"
|
||||
#include "protoutils.h"
|
||||
|
||||
/**
|
||||
* Normally, addresses have been represented using string addresses, like:
|
||||
|
||||
tcp4://127.0.0.1:1234
|
||||
udp4://10.20.30.40:5060
|
||||
ws://1.2.3.4:5678
|
||||
tcp6://[1fff:0:a88:85a3::ac1f]:8001
|
||||
This isn't optimal. Instead, addresses should be formatted so:
|
||||
|
||||
Binary format:
|
||||
|
||||
(varint proto><n byte addr>)+
|
||||
<1 byte ipv4 code><4 byte ipv4 addr><1 byte udp code><2 byte udp port>
|
||||
<1 byte ipv6 code><16 byte ipv6 addr><1 byte tcp code><2 byte tcp port>
|
||||
|
||||
String format:
|
||||
|
||||
(/<addr str code>/<addr str rep>)+
|
||||
/ip4/<ipv4 str addr>/udp/<udp int port>
|
||||
/ip6/<ipv6 str addr>/tcp/<tcp int port>
|
||||
*/
|
||||
|
||||
struct MultiAddress
|
||||
{
|
||||
// A MultiAddress represented as a string
|
||||
char* string;
|
||||
// A MultiAddress represented as an array of bytes
|
||||
//<varint proto><n byte addr><1 byte protocol code><4 byte ipv4 address or 16 byte ipv6 address><1 byte tcp/udp code><2 byte port>
|
||||
uint8_t* bytes;
|
||||
size_t bsize;
|
||||
};
|
||||
|
||||
|
||||
int strpos(char *haystack, char *needle);
|
||||
|
||||
struct MultiAddress* multiaddress_new_from_bytes(const uint8_t* byteaddress, int size); //Construct new address from bytes
|
||||
|
||||
struct MultiAddress* multiaddress_new_from_string(const char* straddress); //Construct new address from string
|
||||
|
||||
void multiaddress_free(struct MultiAddress* in);
|
||||
|
||||
struct MultiAddress* multiaddress_copy(const struct MultiAddress* source);
|
||||
|
||||
// helpers to parse the MultiAddress struct
|
||||
|
||||
int multiaddress_encapsulate(struct MultiAddress * result, char * string);
|
||||
|
||||
int multiaddress_decapsulate(struct MultiAddress * result, char * srci);
|
||||
|
||||
int multiaddress_is_ip(const struct MultiAddress* in);
|
||||
|
||||
int multiaddress_is_ip4(const struct MultiAddress* in);
|
||||
|
||||
int multiaddress_is_ip6(const struct MultiAddress* in);
|
||||
|
||||
int multiaddress_get_ip_family(const struct MultiAddress* in);
|
||||
|
||||
/***
|
||||
* Pulls the textual representation of the IP address from a multihash
|
||||
* @param in the multihash to parse
|
||||
* @param ip where to put the ip address
|
||||
* @returns true(1) on success, otherwise 0
|
||||
*/
|
||||
int multiaddress_get_ip_address(const struct MultiAddress* in, char** ip);
|
||||
|
||||
/***
|
||||
* Pulls the IP port from a multiaddress
|
||||
* @param in the multiaddress
|
||||
* @param port where to put the port
|
||||
* @returns the port, or a negative number for an error
|
||||
*/
|
||||
int multiaddress_get_ip_port(const struct MultiAddress* in);
|
||||
|
||||
/**
|
||||
* Pulls the peer ID out of a multiaddress struct
|
||||
* @param in the MultiAddress
|
||||
* @returns the peer id string, or NULL NOTE: This allocates memory that needs to be freed
|
||||
*/
|
||||
char* multiaddress_get_peer_id(const struct MultiAddress* in);
|
||||
|
||||
/**
|
||||
* Check to see how these two addresses compare
|
||||
* @param a side A
|
||||
* @param b side B
|
||||
* @returns <0 if B > A; >0 if A > B; 0 if A == B
|
||||
*/
|
||||
int multiaddress_compare(const struct MultiAddress* a, const struct MultiAddress* b);
|
||||
|
||||
/**
|
||||
* Check to see how these two addresses compare, ignoring IP address, only looking at ID hash
|
||||
* @param a side A
|
||||
* @param b side B
|
||||
* @returns <0 if B > A; >0 if A > B; 0 if A == B
|
||||
*/
|
||||
int multiaddress_compare_id(const struct MultiAddress* a, const struct MultiAddress* b);
|
||||
|
||||
#endif
|
|
@ -1,40 +0,0 @@
|
|||
#ifndef PROTOCOLS
|
||||
#define PROTOCOLS
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include "varhexutils.h"
|
||||
|
||||
struct Protocol
|
||||
{
|
||||
//char hexcode[21];
|
||||
int deccode;
|
||||
int size;
|
||||
char name[30];
|
||||
};
|
||||
|
||||
struct ProtocolListItem {
|
||||
struct Protocol* current;
|
||||
struct ProtocolListItem* next;
|
||||
};
|
||||
|
||||
int protocol_REMOVE_id(struct ProtocolListItem* head, int remid); //Function to remove & shift back all data, sort of like c++ vectors.
|
||||
|
||||
void unload_protocols(struct ProtocolListItem* head);
|
||||
|
||||
/**
|
||||
* load the available protocols into the global protocol_P
|
||||
* @returns True(1) on success, otherwise 0
|
||||
*/
|
||||
int load_protocols(struct ProtocolListItem** head);
|
||||
|
||||
struct Protocol * proto_with_name(const struct ProtocolListItem* head, const char* proto_w_name); //Search for protocol with inputted name
|
||||
|
||||
struct Protocol * proto_with_deccode(const struct ProtocolListItem* head, int proto_w_deccode); //Search for protocol with inputted deccode
|
||||
|
||||
void protocols_with_string(const struct ProtocolListItem* head, char * meee, int sizi); // NOT FINISHED, DO NOT USE!
|
||||
|
||||
#endif
|
|
@ -1,55 +0,0 @@
|
|||
#ifndef PROTOUTILS
|
||||
#define PROTOUTILS
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
char ASCII2bits(char ch);
|
||||
|
||||
void hex2bin (char *dst, char *src, int len);
|
||||
|
||||
char bits2ASCII(char b);
|
||||
|
||||
void bin2hex (char *dst, char *src, int len);
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
//IPv4 VALIDATOR
|
||||
#define DELIM "."
|
||||
|
||||
/* return 1 if string contain only digits, else return 0 */
|
||||
int valid_digit(char *ip_str);
|
||||
|
||||
/* return 1 if IP string is valid, else return 0 */
|
||||
int is_valid_ipv4(char *ip_str);
|
||||
|
||||
//////////////IPv6 Validator
|
||||
#define MAX_HEX_NUMBER_COUNT 8
|
||||
|
||||
int ishexdigit(char ch);
|
||||
|
||||
int is_valid_ipv6(char *str);
|
||||
|
||||
uint64_t ip2int(const char * ipconvertint);
|
||||
|
||||
char * int2ip(int inputintip);
|
||||
|
||||
/**
|
||||
* Unserialize the bytes into a string
|
||||
* @param results where to put the resultant string
|
||||
* @param bytes the bytes to unserialize
|
||||
* @param bytes_size the length of the bytes array
|
||||
*/
|
||||
int bytes_to_string(char** results, const uint8_t* bytes, int bytes_size);
|
||||
|
||||
/**
|
||||
* Convert an address string to a byte representation
|
||||
* @param protocol the protocol to use
|
||||
* @param incoming the byte array
|
||||
* @param incoming_size the size of the byte array
|
||||
* @param results the results
|
||||
* @param results_size the size of the results
|
||||
* @returns the results array
|
||||
*/
|
||||
char * address_string_to_bytes(struct Protocol *protocol, const char *incoming, size_t incoming_size, char** results, int *results_size);
|
||||
|
||||
int string_to_bytes(uint8_t** finalbytes,size_t* realbbsize, const char * strx, size_t strsize);
|
||||
|
||||
#endif
|
|
@ -1,60 +0,0 @@
|
|||
#ifndef VARHEXUTILS
|
||||
#define VARHEXUTILS
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include "varint.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "endian.h"
|
||||
/*uint8_t * encode_big_endian_32(uint32_t ebex32)
|
||||
{
|
||||
uint8_t encbe[10] = {0};
|
||||
memcpy(encbe, htobe32(ebex32));
|
||||
return encbe;
|
||||
}*/
|
||||
int8_t Var_Bytes_Count(uint8_t * countbytesofthis);
|
||||
|
||||
uint8_t * Num_To_Varint_64(uint64_t TOV64INPUT); //UINT64_T TO VARINT
|
||||
|
||||
uint8_t * Num_To_Varint_32(uint32_t TOV32INPUT); // UINT32_T TO VARINT
|
||||
|
||||
uint64_t * Varint_To_Num_64(uint8_t TON64INPUT[60]); //VARINT TO UINT64_t
|
||||
|
||||
uint32_t * Varint_To_Num_32(uint8_t TON32INPUT[60]); //VARINT TO UINT32_t
|
||||
|
||||
//
|
||||
char * Int_To_Hex(uint64_t int2hex); //VAR[binformat] TO HEX
|
||||
|
||||
uint64_t Hex_To_Int(char * hax);
|
||||
|
||||
/**
|
||||
* Convert binary array to array of hex values
|
||||
* @param incoming the binary array
|
||||
* @param incoming_size the size of the incoming array
|
||||
* @returns the allocated array
|
||||
*/
|
||||
unsigned char *Var_To_Hex(const char *incoming, int incoming_size);
|
||||
|
||||
/**
|
||||
* Turn a hex string into a byte array
|
||||
* @param incoming a string of hex values
|
||||
* @param num_bytes the size of the result
|
||||
* @returns a pointer to the converted value
|
||||
*/
|
||||
unsigned char* Hex_To_Var(char * Hexstr, size_t* num_bytes);
|
||||
|
||||
//
|
||||
void convert(char * convert_result, uint8_t * buf); //Both of them read them properly.
|
||||
|
||||
char * Num_To_HexVar_64(uint64_t TOHVINPUT); //UINT64 TO HEXIFIED VAR
|
||||
|
||||
void convert2(char * convert_result2, uint8_t * bufhx);
|
||||
|
||||
char * Num_To_HexVar_32(uint32_t TOHVINPUT); //UINT32 TO HEXIFIED VAR
|
||||
|
||||
uint64_t HexVar_To_Num_64(char * theHEXstring); //HEXIFIED VAR TO UINT64_T
|
||||
|
||||
uint32_t HexVar_To_Num_32(char theHEXstring[]); //HEXIFIED VAR TO UINT32_T
|
||||
|
||||
#endif
|
397
multiaddr.c
397
multiaddr.c
|
@ -1,397 +0,0 @@
|
|||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "multiaddr/varhexutils.h"
|
||||
#include "multiaddr/varint.h"
|
||||
#include "multiaddr/protocols.h"
|
||||
#include "multiaddr/protoutils.h"
|
||||
#include "multiaddr/multiaddr.h"
|
||||
|
||||
int strpos(char *haystack, char *needle)
|
||||
{
|
||||
char *p = strstr(haystack, needle);
|
||||
if (p)
|
||||
{
|
||||
return p - haystack;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1; // Not found = -1.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new MultiAddress struct
|
||||
* @returns an empty MultiAddress struct
|
||||
*/
|
||||
struct MultiAddress* multiaddress_new() {
|
||||
struct MultiAddress* out = (struct MultiAddress*)malloc(sizeof(struct MultiAddress));
|
||||
if (out != NULL) {
|
||||
out->bsize = 0;
|
||||
out->bytes = NULL;
|
||||
out->string = NULL;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* construct a new MultiAddress from bytes
|
||||
* @param byteaddress the byte array
|
||||
* @param size the size of the byte array
|
||||
* @returns a new MultiAddress struct filled in, or NULL on error
|
||||
*/
|
||||
struct MultiAddress* multiaddress_new_from_bytes(const uint8_t* byteaddress, int size)//Construct new address from bytes
|
||||
{
|
||||
struct MultiAddress* out = multiaddress_new();
|
||||
if (out != NULL) {
|
||||
if(byteaddress!=NULL)
|
||||
{
|
||||
out->bytes = malloc(size);
|
||||
if (out->bytes == NULL) {
|
||||
multiaddress_free(out);
|
||||
return NULL;
|
||||
}
|
||||
out->bsize = size;
|
||||
memcpy(out->bytes, byteaddress, size);
|
||||
if(!bytes_to_string(&out->string,byteaddress,size))
|
||||
{
|
||||
multiaddress_free(out);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
multiaddress_free(out);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
struct MultiAddress* multiaddress_new_from_string(const char* straddress)//Construct new address from string
|
||||
{
|
||||
struct MultiAddress* out = multiaddress_new();
|
||||
if (out != NULL) {
|
||||
out->string = malloc(strlen(straddress) + 1);
|
||||
if (out->string == NULL) {
|
||||
multiaddress_free(out);
|
||||
return NULL;
|
||||
}
|
||||
strcpy(out->string, straddress);
|
||||
|
||||
if (string_to_bytes(&(out->bytes), &out->bsize, out->string, strlen(out->string)) == 0 )
|
||||
{
|
||||
multiaddress_free(out);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
int multiaddress_is_ip(const struct MultiAddress* in) {
|
||||
if (in->bytes > 0) {
|
||||
int byte = in->bytes[0];
|
||||
|
||||
if (byte == 4 || byte == 41)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int multiaddress_is_ip4(const struct MultiAddress* in) {
|
||||
return in->bytes[0] == 4;
|
||||
}
|
||||
|
||||
int multiaddress_is_ip6(const struct MultiAddress* in) {
|
||||
return in->bytes[0] == 41;
|
||||
}
|
||||
|
||||
|
||||
int multiaddress_get_ip_family(const struct MultiAddress* in) {
|
||||
if (in->bytes[0] == 4)
|
||||
return AF_INET;
|
||||
if (in->bytes[0] == 41)
|
||||
return AF_INET6;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***
|
||||
* Pulls the textual representation of the IP address from a multihash
|
||||
* @param in the multihash to parse
|
||||
* @param ip where to put the ip address
|
||||
* @returns true(1) on success, otherwise 0
|
||||
*/
|
||||
int multiaddress_get_ip_address(const struct MultiAddress* in, char** ip) {
|
||||
// the incoming address is not what was expected
|
||||
if (strncmp(in->string, "/ip4/", 5) != 0 && strncmp(in->string, "/ip6/", 5) != 0)
|
||||
return 0;
|
||||
if (strstr(in->string, "/tcp/") == NULL && strstr(in->string, "/udp/") == NULL)
|
||||
return 0;
|
||||
// ip
|
||||
char* str = malloc(strlen(in->string));
|
||||
if (str == NULL)
|
||||
return 0;
|
||||
strcpy(str, &in->string[5]); // gets rid of /ip4/
|
||||
char* pos = strchr(str, '/');
|
||||
pos[0] = 0;
|
||||
*ip = malloc(strlen(str) + 1);
|
||||
strcpy(*ip, str);
|
||||
free(str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/***
|
||||
* Pulls the IP port from a multiaddress
|
||||
* @param in the multiaddress
|
||||
* @param port where to put the port
|
||||
* @returns the port, or a negative number for an error
|
||||
*/
|
||||
int multiaddress_get_ip_port(const struct MultiAddress* in) {
|
||||
char* ptr = strstr(in->string, "/tcp/");
|
||||
if (ptr == NULL)
|
||||
ptr = strstr(in->string, "/udp/");
|
||||
if (ptr == NULL)
|
||||
return -1;
|
||||
ptr += 5;
|
||||
char* end_ptr = strstr(ptr, "/");
|
||||
if (end_ptr == NULL) {
|
||||
return atoi(ptr);
|
||||
}
|
||||
char str[end_ptr - ptr + 1];
|
||||
memcpy(str, ptr, end_ptr - ptr);
|
||||
str[end_ptr-ptr] = '\0';
|
||||
return atoi(str);
|
||||
}
|
||||
|
||||
char* multiaddress_get_peer_id(const struct MultiAddress* in) {
|
||||
char* result = NULL;
|
||||
int str_len = 0;
|
||||
char* slash = NULL;
|
||||
char* ptr = NULL;
|
||||
|
||||
ptr = strstr(in->string, "/ipfs/");
|
||||
if (ptr != NULL && ptr[6] != 0) {
|
||||
ptr += 6;
|
||||
str_len = strlen(ptr);
|
||||
slash = strchr(ptr, '/');
|
||||
if (slash != NULL) {
|
||||
str_len = slash - ptr;
|
||||
}
|
||||
if (str_len > 0) {
|
||||
result = malloc(str_len + 1);
|
||||
if (result != NULL) {
|
||||
memset(result, 0, str_len + 1);
|
||||
memcpy(result, ptr, str_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void multiaddress_free(struct MultiAddress* in) {
|
||||
if (in != NULL) {
|
||||
if (in->bytes != NULL)
|
||||
free(in->bytes);
|
||||
if (in->string != NULL)
|
||||
free(in->string);
|
||||
free(in);
|
||||
in = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a multiaddress from one memory location to another
|
||||
* @param in the source
|
||||
* @returns the new struct MultiAddress or NULL if there was a problem (i.e. out of memory)
|
||||
*/
|
||||
struct MultiAddress* multiaddress_copy(const struct MultiAddress* in) {
|
||||
struct MultiAddress* out = NULL;
|
||||
if (in != NULL) {
|
||||
out = (struct MultiAddress*)malloc(sizeof(struct MultiAddress));
|
||||
if (out != NULL) {
|
||||
if (in->bsize > 0) {
|
||||
out->bytes = malloc(in->bsize);
|
||||
if (out->bytes == NULL) {
|
||||
free(out);
|
||||
return NULL;
|
||||
}
|
||||
out->bsize = in->bsize;
|
||||
memcpy(out->bytes, in->bytes, out->bsize);
|
||||
} // bytes need to be copied
|
||||
if (in->string != NULL) {
|
||||
out->string = malloc(strlen(in->string) + 1);
|
||||
if (out->string == NULL) {
|
||||
if (out->bsize > 0)
|
||||
free(out->bytes);
|
||||
free(out);
|
||||
return NULL;
|
||||
}
|
||||
strcpy(out->string, in->string);
|
||||
} // string needs to be copied
|
||||
} // structure allocated
|
||||
} // good parameters
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Put a string into the MultiAddress and recalculate the bytes
|
||||
* @param result the struct
|
||||
* @param string the new string
|
||||
*/
|
||||
int multiaddress_encapsulate(struct MultiAddress* result, char* string)
|
||||
{
|
||||
if(result != NULL && string != NULL)
|
||||
{
|
||||
// remove the old values
|
||||
if (result->bytes != NULL)
|
||||
free(result->bytes);
|
||||
result->bytes = NULL;
|
||||
result->bsize = 0;
|
||||
char * exstr;
|
||||
if(string[0] == '/')
|
||||
{
|
||||
exstr = (char *) malloc(strlen(result->string)+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
exstr = (char *) malloc(strlen(result->string));
|
||||
}
|
||||
strcpy(exstr, result->string);
|
||||
free(result->string);
|
||||
// insert the new values
|
||||
result->string = malloc(strlen(string) + strlen(exstr) + 1);
|
||||
if (result->string == NULL) {
|
||||
multiaddress_free(result);
|
||||
return 0;
|
||||
}
|
||||
strcpy(result->string, exstr);
|
||||
free(exstr);
|
||||
if(string[0] == '/')
|
||||
{
|
||||
strcat(result->string, string+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcat(result->string, string);
|
||||
}
|
||||
if(string_to_bytes(&result->bytes, &result->bsize, result->string, strlen(result->string)+1) == 0)
|
||||
{
|
||||
multiaddress_free(result);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find scri and remove it from the resultant value
|
||||
* (ie /ip4/127.0.0.1/tcp/4001 becomes ip4/127.0.0.1 when you call decapsulate(addr, "/tcp")
|
||||
* @param result the address to work with
|
||||
* @param srci the string to look for
|
||||
*/
|
||||
int multiaddress_decapsulate(struct MultiAddress * result, char * srci)
|
||||
{
|
||||
if(result!=NULL && srci!=NULL)
|
||||
{
|
||||
char * procstr = NULL;
|
||||
procstr = result->string;
|
||||
int i=0;
|
||||
int sz=strlen(procstr);
|
||||
char * src = NULL;
|
||||
src=srci;
|
||||
// change slash to space
|
||||
for(i=0;i<sz;i++)
|
||||
{
|
||||
if(procstr[i] == '/')
|
||||
{
|
||||
procstr[i]=' ';
|
||||
}
|
||||
}
|
||||
int pos=-1;
|
||||
pos=strpos(procstr,src);
|
||||
if(pos!=-1)
|
||||
{
|
||||
// fill rest with 0s
|
||||
for(i=pos;i<sz;i++)
|
||||
{
|
||||
procstr[i] = '\0';
|
||||
}
|
||||
// replace space with slash
|
||||
for(i=0;i<sz;i++)
|
||||
{
|
||||
if(procstr[i] == ' ')
|
||||
{
|
||||
procstr[i] = '/';
|
||||
}
|
||||
}
|
||||
//Bytes update
|
||||
if (result->bytes != NULL)
|
||||
free(result->bytes);
|
||||
result->bytes = NULL;
|
||||
result->bsize = 0;
|
||||
if(string_to_bytes(&result->bytes, &result->bsize, result->string, strlen(result->string)+1) == 0)
|
||||
{
|
||||
multiaddress_free(result);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see how these two addresses compare
|
||||
* @param a side A
|
||||
* @param b side B
|
||||
* @returns <0 if B > A; >0 if A > B; 0 if A == B
|
||||
*/
|
||||
int multiaddress_compare(const struct MultiAddress* a, const struct MultiAddress* b) {
|
||||
if (a == NULL && b == NULL)
|
||||
return 0;
|
||||
if (a == NULL && b != NULL)
|
||||
return -1;
|
||||
if (a != NULL && b == NULL)
|
||||
return 1;
|
||||
int total = b->bsize - a->bsize;
|
||||
if (total != 0)
|
||||
return total;
|
||||
for(size_t i = 0; i < b->bsize; i++) {
|
||||
total = b->bytes[i] - a->bytes[i];
|
||||
if (total != 0)
|
||||
return total;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see how these two addresses compare, ignoring IP address,
|
||||
* only looking at the first /ipfs/ID hash
|
||||
* @param a side A
|
||||
* @param b side B
|
||||
* @returns <0 if B > A; >0 if A > B; 0 if A == B
|
||||
*/
|
||||
int multiaddress_compare_id(const struct MultiAddress* a, const struct MultiAddress* b) {
|
||||
char* a_id = multiaddress_get_peer_id(a);
|
||||
char* b_id = multiaddress_get_peer_id(b);
|
||||
if (a_id == NULL && b_id == NULL)
|
||||
return 0;
|
||||
if (a_id == NULL && b_id != NULL)
|
||||
return -1;
|
||||
if (a_id != NULL && b_id == NULL)
|
||||
return 1;
|
||||
int retVal = strcmp(a_id, b_id);
|
||||
if (a_id != NULL)
|
||||
free(a_id);
|
||||
if (b_id != NULL)
|
||||
free(b_id);
|
||||
return retVal;
|
||||
}
|
||||
|
30
proto-dat
30
proto-dat
|
@ -1,15 +1,15 @@
|
|||
hex-code dec-code size name
|
||||
04 4 32 ip4
|
||||
29 41 128 ip6
|
||||
06 6 16 tcp
|
||||
11 17 16 udp
|
||||
21 33 16 dccp
|
||||
84 132 16 sctp
|
||||
12D 301 0 udt
|
||||
12E 302 0 utp
|
||||
2A 42 -1 ipfs
|
||||
1E0 480 0 http
|
||||
1BB 443 0 https
|
||||
1DD 477 0 ws
|
||||
1BC 444 10 onion
|
||||
113 275 0 libp2p-webrtc-star
|
||||
hex-code dec-code size name
|
||||
84000000000000000000 4 32 ip4
|
||||
A9000000000000000000 41 128 ip6
|
||||
86000000000000000000 6 16 tcp
|
||||
91000000000000000000 17 16 udp
|
||||
A1000000000000000000 33 16 dccp
|
||||
84810000000000000000 132 16 sctp
|
||||
AD820000000000000000 301 0 udt
|
||||
AE820000000000000000 302 0 utp
|
||||
AA000000000000000000 42 -1 ipfs
|
||||
E0830000000000000000 480 0 http
|
||||
BB830000000000000000 443 0 https
|
||||
DD830000000000000000 477 0 ws
|
||||
BC830000000000000000 444 10 onion
|
||||
93820000000000000000 275 0 libp2p-webrtc-star
|
||||
|
|
|
@ -1,28 +1,35 @@
|
|||
#ifndef PROTOCOLS
|
||||
#define PROTOCOLS
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "multiaddr/protocols.h"
|
||||
#include "multiaddr/varhexutils.h"
|
||||
|
||||
/*
|
||||
int protocol_REMOVE_id(struct ProtocolListItem* protocol_P, int remid)//Function to remove & shift back all data, sort of like c++ vectors.
|
||||
#include "varhexutils.h"
|
||||
int CNT_PROTOCOLNUM=0;
|
||||
struct protocol
|
||||
{
|
||||
char hexcode[21];
|
||||
int deccode;
|
||||
int size;
|
||||
char name[30];
|
||||
};
|
||||
struct protocol *protocol_P; //Pointer for holding multiple structures
|
||||
int protocol_REMOVE_id(int remid)//Function to remove & shift back all data, sort of like c++ vectors.
|
||||
{
|
||||
|
||||
if(remid < CNT_PROTOCOLNUM && remid >= 0&&CNT_PROTOCOLNUM!=0) //Checking to see if remid actually exists.
|
||||
{
|
||||
for(int i=remid; i<CNT_PROTOCOLNUM-1; ++i) //While i < num of registered protocols //Needs to be tested that -1 is for valgrind debugging
|
||||
for(int i=remid; i<CNT_PROTOCOLNUM; ++i) //While i < num of registered protocols
|
||||
{
|
||||
//strcpy((protocol_P+i)->hexcode, (protocol_P+i+1)->hexcode); //shift memory to the user we want to remove.
|
||||
strcpy((protocol_P+i)->hexcode, (protocol_P+i+1)->hexcode); //shift memory to the user we want to remove.
|
||||
(protocol_P+i)->deccode = (protocol_P+i+1)->deccode; //Same as above
|
||||
(protocol_P+i)->size = (protocol_P+i+1)->size; //Same as above
|
||||
strcpy((protocol_P+i)->name, (protocol_P+i+1)->name); //Same as above
|
||||
}//Overwriting user done. Time to get rid of that extra memory.
|
||||
protocol_P = (struct Protocol*) realloc(protocol_P, (CNT_PROTOCOLNUM-1) * sizeof(struct Protocol));
|
||||
//Memory erased,
|
||||
protocol_P = (struct protocol*) realloc(protocol_P, (CNT_PROTOCOLNUM-1) * sizeof(struct protocol));
|
||||
//Memory erased,
|
||||
CNT_PROTOCOLNUM--; //Since the record no longer exists, we should decrease the ammount of users.
|
||||
return 1; //Purely for error checking, in case someone ever wants it/
|
||||
} //1 = Success
|
||||
|
@ -39,52 +46,12 @@ int protocol_REMOVE_id(struct ProtocolListItem* protocol_P, int remid)//Function
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void unload_protocols(struct ProtocolListItem* head)
|
||||
void unload_protocols()
|
||||
{
|
||||
struct ProtocolListItem* current = head;
|
||||
while (current != NULL) {
|
||||
struct ProtocolListItem* next = current->next;
|
||||
free(current->current);
|
||||
free(current);
|
||||
current = next;
|
||||
}
|
||||
free(protocol_P);
|
||||
}
|
||||
|
||||
/**
|
||||
* load the available protocols into the global protocol_P
|
||||
* @returns True(1) on success, otherwise 0
|
||||
*/
|
||||
int load_protocols(struct ProtocolListItem** head)
|
||||
void load_protocols()
|
||||
{
|
||||
unload_protocols(*head);
|
||||
int num_protocols = 14;
|
||||
int dec_code[] = {4, 41, 6, 17, 33, 132, 301, 302, 42, 480, 443, 477, 444, 275};
|
||||
int size[] = {32, 128, 16, 16, 16, 16, 0, 0, -1, 0, 0, 0, 10, 0 };
|
||||
char* name[] = { "ip4", "ip6", "tcp", "udp", "dccp", "sctp", "udt", "utp", "ipfs", "http", "https", "ws", "onion", "libp2p-webrtc-star" };
|
||||
struct ProtocolListItem* last = NULL;
|
||||
for(int i = 0; i < num_protocols; i++) {
|
||||
struct ProtocolListItem* current_item = (struct ProtocolListItem*)malloc(sizeof(struct ProtocolListItem));
|
||||
current_item->current = (struct Protocol*)malloc(sizeof(struct Protocol));
|
||||
current_item->next = NULL;
|
||||
current_item->current->deccode = dec_code[i];
|
||||
strcpy(current_item->current->name, name[i]);
|
||||
current_item->current->size = size[i];
|
||||
if (*head == NULL) {
|
||||
*head = current_item;
|
||||
} else {
|
||||
last->next = current_item;
|
||||
}
|
||||
last = current_item;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
void load_protocols_from_file(struct Protocol** in)
|
||||
{
|
||||
struct Protocol* protocol_P = *in;
|
||||
FILE *FPROC_POINT; //File pointer.
|
||||
FPROC_POINT = fopen("proto-dat", "r");//Opening proto-dat Or protocols.csv, I just formatted it to my liking.
|
||||
if(FPROC_POINT != NULL) //While pointer is not null.
|
||||
|
@ -99,13 +66,13 @@ void load_protocols_from_file(struct Protocol** in)
|
|||
//ADD MEMORY FOR NEW PROTOCOL
|
||||
if(CNT_PROTOCOLNUM==0) //If there are no registered protocols yet, allocate memory to pointer.
|
||||
{
|
||||
protocol_P = (struct Protocol*) malloc (sizeof(struct Protocol));
|
||||
protocol_P = (struct protocol*) malloc (sizeof(struct protocol));
|
||||
}
|
||||
else //Reallocate memory to fit one more Protocol
|
||||
else //Reallocate memory to fit one more protocol
|
||||
{
|
||||
protocol_P = (struct Protocol*) realloc(protocol_P, (CNT_PROTOCOLNUM+1) * sizeof(struct protocol));
|
||||
protocol_P = (struct protocol*) realloc(protocol_P, (CNT_PROTOCOLNUM+1) * sizeof(struct protocol));
|
||||
}
|
||||
//strcpy((protocol_P+CNT_PROTOCOLNUM)->hexcode, W_BUFF); //Copy word to structure at hexcode A hexcode is a string so we keep it as such
|
||||
strcpy((protocol_P+CNT_PROTOCOLNUM)->hexcode, W_BUFF); //Copy word to structure at hexcode A hexcode is a string so we keep it as such
|
||||
break;
|
||||
}
|
||||
case 1://Second word - DECCODE
|
||||
|
@ -133,42 +100,52 @@ void load_protocols_from_file(struct Protocol** in)
|
|||
}
|
||||
}
|
||||