summaryrefslogtreecommitdiff
path: root/attic/historic/anode/libanode/anode.h
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2017-05-04 10:42:22 -0700
committerAdam Ierymenko <adam.ierymenko@gmail.com>2017-05-04 10:42:22 -0700
commit54c47a1e03b5a7446315fc2cff64fb93fd85c5b7 (patch)
tree9298a528541fe19c7de8ac086da0b6b39b319757 /attic/historic/anode/libanode/anode.h
parent6bb855873d98309cf7ae9ed117615638366e5d8b (diff)
downloadinfinitytier-54c47a1e03b5a7446315fc2cff64fb93fd85c5b7.tar.gz
infinitytier-54c47a1e03b5a7446315fc2cff64fb93fd85c5b7.zip
Add some historic code just for the heck of it.
Diffstat (limited to 'attic/historic/anode/libanode/anode.h')
-rw-r--r--attic/historic/anode/libanode/anode.h795
1 files changed, 795 insertions, 0 deletions
diff --git a/attic/historic/anode/libanode/anode.h b/attic/historic/anode/libanode/anode.h
new file mode 100644
index 00000000..e0c51e2e
--- /dev/null
+++ b/attic/historic/anode/libanode/anode.h
@@ -0,0 +1,795 @@
+/* libanode: the Anode C reference implementation
+ * Copyright (C) 2009-2010 Adam Ierymenko <adam.ierymenko@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef _ANODE_ANODE_H
+#define _ANODE_ANODE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+#define ANODE_ADDRESS_LENGTH_ANODE_256_40 40
+#define ANODE_ADDRESS_MAX_LENGTH 40
+#define ANODE_ADDRESS_SECRET_LENGTH_ANODE_256_40 32
+#define ANODE_ADDRESS_MAX_SECRET_LENGTH 32
+
+#define ANODE_ADDRESS_ID_LENGTH 8
+#define ANODE_ZONE_LENGTH 4
+
+#define ANODE_ERR_NONE 0
+#define ANODE_ERR_INVALID_ARGUMENT (-10000)
+#define ANODE_ERR_OUT_OF_MEMORY (-10001)
+#define ANODE_ERR_INVALID_URI (-10002)
+#define ANODE_ERR_BUFFER_TOO_SMALL (-10003)
+#define ANODE_ERR_ADDRESS_INVALID (-10010)
+#define ANODE_ERR_ADDRESS_TYPE_NOT_SUPPORTED (-10011)
+#define ANODE_ERR_CONNECTION_CLOSED (-10012)
+#define ANODE_ERR_CONNECTION_CLOSED_BY_REMOTE (-10013)
+#define ANODE_ERR_CONNECT_FAILED (-10014)
+#define ANODE_ERR_UNABLE_TO_BIND (-10015)
+#define ANODE_ERR_TOO_MANY_OPEN_SOCKETS (-10016)
+#define ANODE_ERR_DNS_NAME_NOT_FOUND_OR_TIMED_OUT (-10017)
+
+/**
+ * Get a human-readable error description for an error code
+ *
+ * The value of 'err' can be either negative or positive.
+ *
+ * @param err Error code
+ * @return Human-readable description
+ */
+extern const char *Anode_strerror(int err);
+
+/* ----------------------------------------------------------------------- */
+/* Secure random source */
+/* ----------------------------------------------------------------------- */
+
+/**
+ * Opaque secure random instance
+ */
+typedef void AnodeSecureRandom;
+
+/**
+ * Initialize a secure random source
+ *
+ * No cleanup/destructor is necessary.
+ *
+ * @param srng Random structure to initialize
+ */
+extern AnodeSecureRandom *AnodeSecureRandom_new();
+
+/**
+ * Generate random bytes
+ *
+ * @param srng Secure random source
+ * @param buf Buffer to fill
+ * @param count Number of bytes to generate
+ */
+extern void AnodeSecureRandom_gen_bytes(AnodeSecureRandom *srng,void *buf,long count);
+
+/**
+ * Destroy and free a secure random instance
+ *
+ * @param srng Secure random source
+ */
+extern void AnodeSecureRandom_delete(AnodeSecureRandom *srng);
+
+/* ----------------------------------------------------------------------- */
+/* AES-256 derived Davis-Meyer hash function */
+/* ----------------------------------------------------------------------- */
+
+/**
+ * Digest a message using AES-DIGEST to yield a 16-byte hash code
+ *
+ * @param message Message to digest
+ * @param message_len Length of message in bytes
+ * @param hash Buffer to store 16 byte hash code
+ */
+extern void Anode_aes_digest(
+ const void *const message,
+ unsigned long message_len,
+ void *const hash);
+
+/* ----------------------------------------------------------------------- */
+/* Address Types and Components */
+/* ----------------------------------------------------------------------- */
+
+/**
+ * Anode address
+ *
+ * The first byte always identifies the address type, which right now can
+ * only be type 1 (ANODE-256-40).
+ */
+typedef struct
+{
+ char bits[ANODE_ADDRESS_MAX_LENGTH];
+} AnodeAddress;
+
+/**
+ * 8-byte short Anode address ID
+ */
+typedef struct
+{
+ char bits[ANODE_ADDRESS_ID_LENGTH];
+} AnodeAddressId;
+
+/**
+ * 4-byte Anode zone ID
+ */
+typedef struct
+{
+ char bits[ANODE_ZONE_LENGTH];
+} AnodeZone;
+
+/**
+ * Anode address types
+ */
+enum AnodeAddressType
+{
+ ANODE_ADDRESS_ANODE_256_40 = 1
+};
+
+/**
+ * Get the type of an Anode address
+ *
+ * This is a shortcut macro for just looking at the first byte and casting
+ * it to the AnodeAddressType enum.
+ *
+ * @param a Pointer to address
+ * @return Type as enum AnodeAddressType
+ */
+#define AnodeAddress_get_type(a) ((enum AnodeAddressType)((a)->bits[0]))
+
+/**
+ * Calculate the short 8 byte address ID from an address
+ *
+ * @param address Binary address
+ * @param short_address_id Buffer to store 8-byte short address ID
+ * @return 0 on success or error code on failure
+ */
+extern int AnodeAddress_calc_short_id(
+ const AnodeAddress *address,
+ AnodeAddressId *short_address_id);
+
+/**
+ * Extract the zone from an anode address
+ *
+ * @param address Binary address
+ * @param zone Zone value-result parameter to fill on success
+ * @return 0 on success or error code on failure
+ */
+extern int AnodeAddress_get_zone(const AnodeAddress *address,AnodeZone *zone);
+
+/**
+ * Convert an address to an ASCII string
+ *
+ * Anode addresses are 64 characters in ASCII form, so the buffer should
+ * have 65 bytes of space.
+ *
+ * @param address Address to convert
+ * @param buf Buffer to receive address in string form (should have 65 bytes of space)
+ * @param len Length of buffer
+ * @return Length of resulting string or a negative error code on error
+ */
+extern int AnodeAddress_to_string(const AnodeAddress *address,char *buf,int len);
+
+/**
+ * Convert a string into an address
+ *
+ * @param str Address in string form
+ * @param address Address buffer to receive result
+ * @return Zero on sucess or error code on error
+ */
+extern int AnodeAddress_from_string(const char *str,AnodeAddress *address);
+
+/**
+ * Supported network address types
+ */
+enum AnodeNetworkAddressType
+{
+ ANODE_NETWORK_ADDRESS_IPV4 = 0,
+ ANODE_NETWORK_ADDRESS_IPV6 = 1,
+ ANODE_NETWORK_ADDRESS_ETHERNET = 2, /* reserved but unused */
+ ANODE_NETWORK_ADDRESS_USB = 3, /* reserved but unused */
+ ANODE_NETWORK_ADDRESS_BLUETOOTH = 4, /* reserved but unused */
+ ANODE_NETWORK_ADDRESS_IPC = 5, /* reserved but unused */
+ ANODE_NETWORK_ADDRESS_80211S = 6, /* reserved but unused */
+ ANODE_NETWORK_ADDRESS_SERIAL = 7, /* reserved but unused */
+ ANODE_NETWORK_ADDRESS_ANODE_256_40 = 8
+};
+
+/**
+ * Anode network address
+ *
+ * This can contain an address of any type: IPv4, IPv6, or Anode, and is used
+ * with the common transport API.
+ *
+ * The length of the address stored in bits[] is determined by the type.
+ */
+typedef struct
+{
+ enum AnodeNetworkAddressType type;
+ char bits[ANODE_ADDRESS_MAX_LENGTH];
+} AnodeNetworkAddress;
+
+/**
+ * An endpoint with an address and a port
+ */
+typedef struct
+{
+ AnodeNetworkAddress address;
+ int port;
+} AnodeNetworkEndpoint;
+
+/* Constants for binding to any address (v4 or v6) */
+extern const AnodeNetworkAddress AnodeNetworkAddress_IP_ANY_V4;
+extern const AnodeNetworkAddress AnodeNetworkAddress_IP_ANY_V6;
+
+/* Local host address in v4 and v6 */
+extern const AnodeNetworkAddress AnodeNetworkAddress_IP_LOCAL_V4;
+extern const AnodeNetworkAddress AnodeNetworkAddress_IP_LOCAL_V6;
+
+/**
+ * Convert a network address to an ASCII string
+ *
+ * The buffer must have room for a 15 character string for IPv4, a 40 byte
+ * string for IPv6, and a 64 byte string for Anode addresses. This does not
+ * include the trailing null.
+ *
+ * @param address Address to convert
+ * @param buf Buffer to receive address in string form
+ * @param len Length of buffer
+ * @return Length of resulting string or a negative error code on error
+ */
+extern int AnodeNetworkAddress_to_string(const AnodeNetworkAddress *address,char *buf,int len);
+
+/**
+ * Convert a string into a network address of the correct type
+ *
+ * @param str Address in string form
+ * @param address Address buffer to receive result
+ * @return Zero on sucess or error code on error
+ */
+extern int AnodeNetworkAddress_from_string(const char *str,AnodeNetworkAddress *address);
+
+/**
+ * Fill a network endpoint from a C-API sockaddr structure
+ *
+ * The argument must be struct sockaddr_in for IPv4 or sockaddr_in6 for IPv6.
+ * The common sin_family field will be used to differentiate.
+ *
+ * @param sockaddr Pointer to proper sockaddr structure
+ * @param endpoint Endpoint structure to fill
+ * @return Zero on success or error on failure
+ */
+extern int AnodeNetworkEndpoint_from_sockaddr(const void *sockaddr,AnodeNetworkEndpoint *endpoint);
+
+/**
+ * Fill a sockaddr from a network endpoint
+ *
+ * To support either IPv4 or IPv6 addresses, there is a sockaddr_storage
+ * structure in most C APIs. If you supply anything other than an IP address
+ * such as an Anode address, this will return an error.
+ *
+ * @param endpoint Endpoint structure to convert
+ * @param sockaddr Sockaddr structure storage
+ * @param sockaddr_len Length of sockaddr structure storage in bytes
+ * @return Zero on success or error on failure
+ */
+extern int AnodeNetworkEndpoint_to_sockaddr(const AnodeNetworkEndpoint *endpoint,void *sockaddr,int sockaddr_len);
+
+/* ----------------------------------------------------------------------- */
+/* Identity Generation and Management */
+/* ----------------------------------------------------------------------- */
+
+/**
+ * Anode identity structure containing address and secret key
+ *
+ * This structure is memcpy-safe, and its members are accessible.
+ */
+typedef struct
+{
+ /* The public Anode address */
+ AnodeAddress address;
+
+ /* Short address ID */
+ AnodeAddressId address_id;
+
+ /* The secret key corresponding with the public address */
+ /* Secret length is determined by address type */
+ char secret[ANODE_ADDRESS_MAX_SECRET_LENGTH];
+} AnodeIdentity;
+
+/**
+ * Generate a new identity
+ *
+ * This generates a public/private key pair and from that generates an
+ * identity containing an address and a secret key.
+ *
+ * @param identity Destination structure to store new identity
+ * @param zone Zone ID
+ * @param type Type of identity to generate
+ * @return Zero on success, error on failure
+ */
+extern int AnodeIdentity_generate(
+ AnodeIdentity *identity,
+ const AnodeZone *zone,
+ enum AnodeAddressType type);
+
+/**
+ * Convert an Anode identity to a string representation
+ *
+ * @param identity Identity to convert
+ * @param dest String buffer
+ * @param dest_len Length of string buffer
+ * @return Length of string created or negative error code on failure
+ */
+extern int AnodeIdentity_to_string(
+ const AnodeIdentity *identity,
+ char *dest,
+ int dest_len);
+
+/**
+ * Convert a string representation to an Anode identity structure
+ *
+ * @param identity Destination structure to fill
+ * @param str C-string containing string representation
+ * @return Zero on success or negative error code on failure
+ */
+extern int AnodeIdentity_from_string(
+ AnodeIdentity *identity,
+ const char *str);
+
+/* ----------------------------------------------------------------------- */
+/* Transport API */
+/* ----------------------------------------------------------------------- */
+
+struct _AnodeTransport;
+typedef struct _AnodeTransport AnodeTransport;
+struct _AnodeEvent;
+typedef struct _AnodeEvent AnodeEvent;
+
+/**
+ * Anode socket
+ */
+typedef struct
+{
+ /* Type of socket (read-only) */
+ enum {
+ ANODE_SOCKET_DATAGRAM = 1,
+ ANODE_SOCKET_STREAM_LISTEN = 2,
+ ANODE_SOCKET_STREAM_CONNECTION = 3
+ } type;
+
+ /* Socket state */
+ enum {
+ ANODE_SOCKET_CLOSED = 0,
+ ANODE_SOCKET_OPEN = 1,
+ ANODE_SOCKET_CONNECTING = 2,
+ } state;
+
+ /* Local address or remote address for stream connections (read-only) */
+ AnodeNetworkEndpoint endpoint;
+
+ /* Name of owning class (read-only) */
+ const char *class_name;
+
+ /* Pointers for end user use (writable) */
+ void *user_ptr[2];
+
+ /* Special handler to receive events or null for default (writable) */
+ void (*event_handler)(const AnodeEvent *event);
+} AnodeSocket;
+
+/**
+ * Anode transport I/O event
+ */
+struct _AnodeEvent
+{
+ enum {
+ ANODE_TRANSPORT_EVENT_DATAGRAM_RECEIVED = 1,
+ ANODE_TRANSPORT_EVENT_STREAM_INCOMING_CONNECT = 2,
+ ANODE_TRANSPORT_EVENT_STREAM_OUTGOING_CONNECT_ESTABLISHED = 3,
+ ANODE_TRANSPORT_EVENT_STREAM_OUTGOING_CONNECT_FAILED = 4,
+ ANODE_TRANSPORT_EVENT_STREAM_CLOSED = 5,
+ ANODE_TRANSPORT_EVENT_STREAM_DATA_RECEIVED = 6,
+ ANODE_TRANSPORT_EVENT_STREAM_AVAILABLE_FOR_WRITE = 7,
+ ANODE_TRANSPORT_EVENT_DNS_RESULT = 8
+ } type;
+
+ AnodeTransport *transport;
+
+ /* Anode socket corresponding to this event */
+ AnodeSocket *sock;
+
+ /* Originating endpoint for incoming datagrams */
+ AnodeNetworkEndpoint *datagram_from;
+
+ /* DNS lookup results */
+ const char *dns_name;
+ AnodeNetworkAddress *dns_addresses;
+ int dns_address_count;
+
+ /* Error code or 0 for none */
+ int error_code;
+
+ /* Data for incoming datagrams and stream received events */
+ int data_length;
+ char *data;
+};
+
+/**
+ * Enum used for dns_resolve method in transport to specify query rules
+ *
+ * This can be specified for ipv4, ipv6, and Anode address types to tell the
+ * DNS resolver when to bother querying for addresses of the given type.
+ * NEVER means to never query for this type, and ALWAYS means to always
+ * query. IF_NO_PREVIOUS means to query for this type if no addresses were
+ * found in previous queries. Addresses are queried in the order of ipv4,
+ * ipv6, then Anode, so if you specify IF_NO_PREVIOUS for all three you will
+ * get addresses in that order of priority.
+ */
+enum AnodeTransportDnsIncludeMode
+{
+ ANODE_TRANSPORT_DNS_QUERY_NEVER = 0,
+ ANODE_TRANSPORT_DNS_QUERY_ALWAYS = 1,
+ ANODE_TRANSPORT_DNS_QUERY_IF_NO_PREVIOUS = 2
+};
+
+struct _AnodeTransport
+{
+ /**
+ * Set the default event handler
+ *
+ * @param transport Transport engine
+ * @param event_handler Default event handler
+ */
+ void (*set_default_event_handler)(AnodeTransport *transport,
+ void (*event_handler)(const AnodeEvent *event));
+
+ /**
+ * Enqueue a function to be executed during a subsequent call to poll()
+ *
+ * This can be called from other threads, so it can be used to pass a
+ * message to the I/O thread in multithreaded applications.
+ *
+ * If it is called from the same thread, the function is still queued to be
+ * run later rather than being run instantly.
+ *
+ * The order in which invoked functions are called is undefined.
+ *
+ * @param transport Transport engine
+ * @param ptr Arbitrary pointer to pass to function to be called
+ * @param func Function to be called
+ */
+ void (*invoke)(AnodeTransport *transport,
+ void *ptr,
+ void (*func)(void *));
+
+ /**
+ * Initiate a forward DNS query
+ *
+ * @param transport Transport instance
+ * @param name DNS name to query
+ * @param event_handler Event handler or null for default event path
+ * @param ipv4_include_mode Inclusion mode for IPv4 addresses
+ * @param ipv6_include_mode Inclusion mode for IPv6 addresses
+ * @param anode_include_mode Inclusion mode for Anode addresses
+ */
+ void (*dns_resolve)(AnodeTransport *transport,
+ const char *name,
+ void (*event_handler)(const AnodeEvent *),
+ enum AnodeTransportDnsIncludeMode ipv4_include_mode,
+ enum AnodeTransportDnsIncludeMode ipv6_include_mode,
+ enum AnodeTransportDnsIncludeMode anode_include_mode);
+
+ /**
+ * Open a datagram socket
+ *
+ * @param transport Transport instance
+ * @param local_address Local address to bind
+ * @param local_port Local port to bind
+ * @param error_code Value-result parameter to receive error code on error
+ * @return Listen socket or null if error (check error_code in error case)
+ */
+ AnodeSocket *(*datagram_listen)(AnodeTransport *transport,
+ const AnodeNetworkAddress *local_address,
+ int local_port,
+ int *error_code);
+
+ /**
+ * Open a socket to listen for incoming stream connections
+ *
+ * @param transport Transport instance
+ * @param local_address Local address to bind
+ * @param local_port Local port to bind
+ * @param error_code Value-result parameter to receive error code on error
+ * @return Listen socket or null if error (check error_code in error case)
+ */
+ AnodeSocket *(*stream_listen)(AnodeTransport *transport,
+ const AnodeNetworkAddress *local_address,
+ int local_port,
+ int *error_code);
+
+ /**
+ * Send a datagram to a network endpoint
+ *
+ * @param transport Transport instance
+ * @param socket Originating datagram socket
+ * @param data Data to send
+ * @param data_len Length of data to send
+ * @param to_endpoint Destination endpoint
+ * @return Zero on success or error code on error
+ */
+ int (*datagram_send)(AnodeTransport *transport,
+ AnodeSocket *sock,
+ const void *data,
+ int data_len,
+ const AnodeNetworkEndpoint *to_endpoint);
+
+ /**
+ * Initiate an outgoing stream connection attempt
+ *
+ * For IPv4 and IPv6 addresses, this will initiate a TCP connection. For
+ * Anode addresses, Anode's internal streaming protocol will be used.
+ *
+ * @param transport Transport instance
+ * @param to_endpoint Destination endpoint
+ * @param error_code Error code value-result parameter, filled on error
+ * @return Stream socket object or null on error (check error_code)
+ */
+ AnodeSocket *(*stream_connect)(AnodeTransport *transport,
+ const AnodeNetworkEndpoint *to_endpoint,
+ int *error_code);
+
+ /**
+ * Indicate that you are interested in writing to a stream
+ *
+ * This does nothing if the socket is not a stream connection or is not
+ * connected.
+ *
+ * @param transport Transport instance
+ * @param sock Stream connection
+ */
+ void (*stream_start_writing)(AnodeTransport *transport,
+ AnodeSocket *sock);
+
+ /**
+ * Indicate that you are no longer interested in writing to a stream
+ *
+ * This does nothing if the socket is not a stream connection or is not
+ * connected.
+ *
+ * @param transport Transport instance
+ * @param sock Stream connection
+ */
+ void (*stream_stop_writing)(AnodeTransport *transport,
+ AnodeSocket *sock);
+
+ /**
+ * Send data to a stream connection
+ *
+ * This must be called after a stream is indicated to be ready for writing.
+ * It returns the number of bytes actually written, or a negative error
+ * code on failure.
+ *
+ * A return value of zero can occur here, and simply indicates that nothing
+ * was sent. This may occur with certain network stacks on certain
+ * platforms.
+ *
+ * @param transport Transport engine
+ * @param sock Stream socket
+ * @param data Data to send
+ * @param data_len Maximum data to send in bytes
+ * @return Actual data sent or negative error code on error
+ */
+ int (*stream_send)(AnodeTransport *transport,
+ AnodeSocket *sock,
+ const void *data,
+ int data_len);
+
+ /**
+ * Close a socket
+ *
+ * If the socket is a stream connection in the connected state, this
+ * will generate a stream closed event with a zero error_code to indicate
+ * a normal close.
+ *
+ * @param transport Transport engine
+ * @param sock Socket object
+ */
+ void (*close)(AnodeTransport *transport,
+ AnodeSocket *sock);
+
+ /**
+ * Run main polling loop
+ *
+ * This should be called repeatedly from the I/O thread of your main
+ * process. It blocks until one or more events occur, and then returns
+ * the number of events. Error returns here are fatal and indicate
+ * serious problems such as build or platform issues or a lack of any
+ * network interface.
+ *
+ * Functions queued with invoke() are also called inside here.
+ *
+ * @param transport Transport engine
+ * @return Number of events handled or negative on (fatal) error
+ */
+ int (*poll)(AnodeTransport *transport);
+
+ /**
+ * Check whether transport supports an address type
+ *
+ * Inheriting classes should call their base if they do not natively
+ * speak the specified type.
+ *
+ * @param transport Transport engine
+ * @param at Address type
+ * @return Nonzero if true
+ */
+ int (*supports_address_type)(const AnodeTransport *transport,
+ enum AnodeNetworkAddressType at);
+
+ /**
+ * Get the instance of AnodeTransport under this one (if any)
+ *
+ * @param transport Transport engine
+ * @return Base instance or null if none
+ */
+ AnodeTransport *(*base_instance)(const AnodeTransport *transport);
+
+ /**
+ * @param transport Transport engine
+ * @return Class name of this instance
+ */
+ const char *(*class_name)(AnodeTransport *transport);
+
+ /**
+ * Delete this transport and its base transports
+ *
+ * The 'transport' pointer and any streams or sockets it owns are no longer
+ * valid after this call.
+ *
+ * @param transport Transport engine
+ */
+ void (*delete)(AnodeTransport *transport);
+};
+
+/**
+ * Construct a new system transport
+ *
+ * This is the default base for AnodeTransport, and it is constructed
+ * automatically if 'base' is null in AnodeTransport_new(). However, it also
+ * exposed to the user so that specialized transports (such as those that use
+ * proxy servers) can be developed on top of it. These in turn can be supplied
+ * as 'base' to AnodeTransport_new() to talk Anode over these transports.
+ *
+ * The system transport supports IP protocols and possibly others.
+ *
+ * @param base Base class or null for none (usually null)
+ * @return Base transport engine instance
+ */
+extern AnodeTransport *AnodeSystemTransport_new(AnodeTransport *base);
+
+/**
+ * Construct a new Anode core transport
+ *
+ * This is the transport that talks Anode using the specified base transport.
+ * Requests for other address types are passed through to the base. If the
+ * base is null, an instance of AnodeSystemTransport is used.
+ *
+ * Since transport engines inherit their functionality, this transport
+ * will also do standard IP and everything else that the system transport
+ * supports. Most users will just want to construct this with a null base.
+ *
+ * @param base Base transport to use, or null to use SystemTransport
+ * @return Anode transport engine or null on error
+ */
+extern AnodeTransport *AnodeCoreTransport_new(AnodeTransport *base);
+
+/* ----------------------------------------------------------------------- */
+/* URI Parser */
+/* ----------------------------------------------------------------------- */
+
+/**
+ * URI broken down by component
+ */
+typedef struct
+{
+ char scheme[8];
+ char username[64];
+ char password[64];
+ char host[128];
+ char path[256];
+ char query[256];
+ char fragment[64];
+ int port;
+} AnodeURI;
+
+/**
+ * URI parser
+ *
+ * A buffer too small error will occur if any field is too large for the
+ * AnodeURI structure.
+ *
+ * @param parsed_uri Structure to fill with parsed URI data
+ * @param uri_string URI in string format
+ * @return Zero on success or error on failure
+ */
+extern int AnodeURI_parse(AnodeURI *parsed_uri,const char *uri_string);
+
+/**
+ * Output a URI in string format
+ *
+ * @param uri URI to output as string
+ * @param buf Buffer to store URI string
+ * @param len Length of buffer
+ * @return Buffer or null on error
+ */
+extern char *AnodeURI_to_string(const AnodeURI *uri,char *buf,int len);
+
+/* ----------------------------------------------------------------------- */
+/* Zone File Lookup and Dictionary */
+/* ----------------------------------------------------------------------- */
+
+/**
+ * Zone file dictionary
+ */
+typedef void AnodeZoneFile;
+
+/**
+ * Start asynchronous zone fetch
+ *
+ * When the zone is retrieved, the lookup handler is called. If zone lookup
+ * failed, the zone file argument to the handler will be null.
+ *
+ * @param transport Transport engine
+ * @param zone Zone ID
+ * @param user_ptr User pointer
+ * @param zone_lookup_handler Handler for Anode zone lookup
+ */
+extern void AnodeZoneFile_lookup(
+ AnodeTransport *transport,
+ const AnodeZone *zone,
+ void *ptr,
+ void (*zone_lookup_handler)(const AnodeZone *,AnodeZoneFile *,void *));
+
+/**
+ * Look up a key in a zone file
+ *
+ * @param zone Zone file object
+ * @param key Key to get in zone file
+ */
+extern const char *AnodeZoneFile_get(const AnodeZoneFile *zone,const char *key);
+
+/**
+ * Free a zone file
+ *
+ * @param zone Zone to free
+ */
+extern void AnodeZoneFile_free(AnodeZoneFile *zone);
+
+/* ----------------------------------------------------------------------- */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif