initial c wrapper
This commit is contained in:
199
i2psam-c.h
Normal file
199
i2psam-c.h
Normal file
@ -0,0 +1,199 @@
|
||||
//
|
||||
// c wrapper for i2psam
|
||||
// Author: jeff
|
||||
// License: MIT
|
||||
// probably contains bugs :-DDDD
|
||||
//
|
||||
#ifndef I2PSAM_C_H
|
||||
#define I2PSAM_C_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct i2psam_destination;
|
||||
struct i2psam_stream_session;
|
||||
struct i2psam_socket;
|
||||
|
||||
struct i2psam_stream_settings
|
||||
{
|
||||
/**
|
||||
hostname of sam interface
|
||||
*/
|
||||
const char * samhost;
|
||||
/**
|
||||
port of sam interface
|
||||
*/
|
||||
const uint16_t samport;
|
||||
/**
|
||||
nickname for sam session
|
||||
*/
|
||||
const char * nickname;
|
||||
/**
|
||||
i2cp options string
|
||||
*/
|
||||
const char * i2cp_opts;
|
||||
/**
|
||||
destination private key
|
||||
*/
|
||||
const char * destination;
|
||||
};
|
||||
|
||||
/**
|
||||
create new stream session
|
||||
*/
|
||||
struct i2psam_stream_session * i2psam_stream_session_new(struct i2psam_stream_settings *);
|
||||
|
||||
/**
|
||||
close and free stream session
|
||||
*/
|
||||
void i2psam_stream_session_free(struct i2psam_stream_session *);
|
||||
|
||||
/**
|
||||
get sam host of stream session
|
||||
@return must be free()'d by caller
|
||||
*/
|
||||
const char * i2psam_get_samhost(struct i2psam_stream_session *);
|
||||
|
||||
/**
|
||||
get sam port of stream session
|
||||
*/
|
||||
uint16_t i2psam_get_samport(struct i2psam_stream_session *);
|
||||
|
||||
/**
|
||||
get sam session's nickname
|
||||
@return must be free()'d by caller
|
||||
*/
|
||||
const char * i2psam_get_nickname(struct i2psam_stream_session *);
|
||||
|
||||
/**
|
||||
get sam session's id
|
||||
@return must be free()'d by caller
|
||||
*/
|
||||
const char * i2psam_get_session_id(struct i2psam_stream_session *);
|
||||
|
||||
/**
|
||||
get min version from sam session's handshake
|
||||
@return must be free()'d by caller
|
||||
*/
|
||||
const char * i2psam_get_sam_min_version(struct i2psam_stream_session *);
|
||||
|
||||
/**
|
||||
get max version from sam session's handshake
|
||||
@return must be free()'d by caller
|
||||
*/
|
||||
const char * i2psam_get_sam_max_version(struct i2psam_stream_session *);
|
||||
|
||||
/**
|
||||
get current version in use with sam session
|
||||
@return must be free()'d by caller
|
||||
*/
|
||||
const char * i2psam_get_sam_version(struct i2psam_stream_session *);
|
||||
|
||||
/**
|
||||
get i2cp options used by sam session
|
||||
@return must be free()'d by caller
|
||||
*/
|
||||
const char * i2psam_get_i2cp_options(struct i2psam_stream_session *);
|
||||
|
||||
/**
|
||||
return 1 if session is sick otherwise returns 0
|
||||
*/
|
||||
int i2psam_is_sick(struct i2psam_stream_session *);
|
||||
|
||||
/**
|
||||
accept a new inbound connection
|
||||
@param silent 0 if we want to obtain the remote's destination, nonzero means don't
|
||||
*/
|
||||
struct i2psam_socket * i2psam_accept(struct i2psam_stream_session *, int silent);
|
||||
|
||||
/**
|
||||
connect to remote destination
|
||||
@param destination full public destination base64 blob
|
||||
@param silent 0 if we want to get verbose error info from connect, nonzero means don't
|
||||
*/
|
||||
struct i2psam_socket * i2psam_connect(struct i2psam_stream_session *, const char * destination, int silent);
|
||||
|
||||
/**
|
||||
forward all inbound connections to a remote endpoint
|
||||
@param host remote hostname of endpoint
|
||||
@param port remote port of endpoint
|
||||
@param silent 0 if we want to be verbose when forwarding to remote endpoint, nonzero means don't
|
||||
@return -1 on fail, otherwise 0
|
||||
*/
|
||||
int i2psam_forward(struct i2psam_stream_session *, const char * host, uint16_t port, int silent);
|
||||
|
||||
/**
|
||||
do a name lookup, if return is non null caller must free()'d
|
||||
@param name the name to resolve
|
||||
@return public destination base64 blob for the name or NULL if the name lookup fails
|
||||
*/
|
||||
const char * i2psam_namelookup(struct i2psam_stream_session *, const char * name);
|
||||
|
||||
/**
|
||||
generate a new i2p destination keypair, return value must be free()'d when done
|
||||
@return newly generated keypair
|
||||
*/
|
||||
struct i2psam_destination * i2psam_dest_generate(struct i2psam_stream_session *);
|
||||
|
||||
/**
|
||||
stop forwarding to remote endpoint
|
||||
@param host hostname of remote endpoint
|
||||
@param port port of remote endpoint
|
||||
*/
|
||||
void i2psam_stop_forwarding(struct i2psam_stream_session*, const char * host, uint16_t port);
|
||||
|
||||
/**
|
||||
stop forwarding to all remote endpoints
|
||||
*/
|
||||
void i2psam_stop_forwarding_all(struct i2psam_stream_session *);
|
||||
|
||||
/**
|
||||
get remote destination for our stream session
|
||||
@return must be free()'d by caller when done with it
|
||||
*/
|
||||
struct i2psam_destination * i2psam_get_my_destination(struct i2psam_stream_session *);
|
||||
|
||||
/**
|
||||
blocking write a buffer of data with an i2psocket
|
||||
@param data buffer to be written
|
||||
@param dlen size of buffer
|
||||
*/
|
||||
void i2psam_write(struct i2psam_socket *, const char * data, size_t dlen);
|
||||
|
||||
/**
|
||||
blocking read on an i2p socket
|
||||
@param pointer to size read
|
||||
@return pointer to read segment, must be free()'d when done if error while reading returns nullptr
|
||||
*/
|
||||
char * i2psam_read(struct i2psam_socket *, size_t * dlen);
|
||||
|
||||
/**
|
||||
close an i2p socket, does not free()
|
||||
*/
|
||||
void i2psam_socket_close(struct i2psam_socket *);
|
||||
|
||||
/**
|
||||
@return 1 if an i2p socket is okay otherwise returns 0
|
||||
*/
|
||||
int i2psam_socket_is_ok(struct i2psam_socket *);
|
||||
|
||||
/**
|
||||
free() an i2p socket, must be closed
|
||||
*/
|
||||
void i2psam_socket_free(struct i2psam_socket *);
|
||||
|
||||
/**
|
||||
get private key for destination as null terminated base64 string
|
||||
@return must be free()'d by caller when done
|
||||
*/
|
||||
const char * i2psam_destination_priv(struct i2psam_destination *);
|
||||
|
||||
/**
|
||||
get public base64 destination blob as null terminated string
|
||||
@return must be free()'d by caller when done
|
||||
*/
|
||||
const char * i2psam_destination_pub(struct i2psam_destination *);
|
||||
|
||||
void i2psam_destination_free(struct i2psam_destination *);
|
||||
|
||||
#endif // I2PSAM_C_H
|
222
i2psam.cpp
222
i2psam.cpp
@ -819,3 +819,225 @@ std::string Message::getValue(const std::string& answer, const std::string& key)
|
||||
|
||||
|
||||
} // namespace SAM
|
||||
|
||||
|
||||
// C interface
|
||||
|
||||
extern "C" {
|
||||
|
||||
#include "i2psam-c.h"
|
||||
|
||||
struct i2psam_stream_session
|
||||
{
|
||||
SAM::StreamSession * impl = nullptr;
|
||||
};
|
||||
|
||||
struct i2psam_socket
|
||||
{
|
||||
std::unique_ptr<SAM::I2pSocket> impl;
|
||||
};
|
||||
|
||||
struct i2psam_destination
|
||||
{
|
||||
char * pub;
|
||||
char * priv;
|
||||
};
|
||||
|
||||
struct i2psam_stream_session * i2psam_stream_session_new(struct i2psam_stream_settings * settings)
|
||||
{
|
||||
struct i2psam_stream_session * session = new i2psam_stream_session;
|
||||
session->impl = new SAM::StreamSession(settings->nickname,
|
||||
settings->samhost,
|
||||
settings->samport,
|
||||
settings->destination,
|
||||
settings->i2cp_opts);
|
||||
return session;
|
||||
}
|
||||
|
||||
void i2psam_stream_session_free(struct i2psam_stream_session * session)
|
||||
{
|
||||
delete session->impl;
|
||||
delete session;
|
||||
}
|
||||
|
||||
const char * i2psam_get_samhost(struct i2psam_stream_session * session)
|
||||
{
|
||||
return strdup(session->impl->getSAMHost().c_str());
|
||||
}
|
||||
|
||||
uint16_t i2psam_get_samport(struct i2psam_stream_session * session)
|
||||
{
|
||||
return session->impl->getSAMPort();
|
||||
}
|
||||
|
||||
const char * i2psam_get_nickname(struct i2psam_stream_session * session)
|
||||
{
|
||||
return strdup(session->impl->getNickname().c_str());
|
||||
}
|
||||
|
||||
const char * i2psam_get_session_id(struct i2psam_stream_session * session)
|
||||
{
|
||||
return strdup(session->impl->getSessionID().c_str());
|
||||
}
|
||||
|
||||
const char * i2psam_get_sam_min_version(struct i2psam_stream_session * session)
|
||||
{
|
||||
return strdup(session->impl->getSAMMinVer().c_str());
|
||||
}
|
||||
|
||||
const char * i2psam_get_sam_max_version(struct i2psam_stream_session * session)
|
||||
{
|
||||
return strdup(session->impl->getSAMMaxVer().c_str());
|
||||
}
|
||||
|
||||
const char * i2psam_get_sam_version(struct i2psam_stream_session * session)
|
||||
{
|
||||
return strdup(session->impl->getSAMVersion().c_str());
|
||||
}
|
||||
|
||||
const char * i2psam_get_i2cp_options(struct i2psam_stream_session * session)
|
||||
{
|
||||
return strdup(session->impl->getOptions().c_str());
|
||||
}
|
||||
|
||||
int i2psam_is_sick(struct i2psam_stream_session * session)
|
||||
{
|
||||
if(session->impl->isSick())
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct i2psam_socket * i2psam_accept(struct i2psam_stream_session * session, int silent)
|
||||
{
|
||||
auto result = session->impl->accept(silent);
|
||||
if (result.isOk)
|
||||
{
|
||||
struct i2psam_socket * socket = new i2psam_socket;
|
||||
socket->impl = std::move(result.value);
|
||||
return socket;
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct i2psam_socket * i2psam_connect(struct i2psam_stream_session * session, const char * destination, int silent)
|
||||
{
|
||||
auto result = session->impl->connect(destination, silent != 0);
|
||||
if(result.isOk)
|
||||
{
|
||||
struct i2psam_socket * socket = new i2psam_socket;
|
||||
socket->impl = std::move(result.value);
|
||||
return socket;
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int i2psam_forward(struct i2psam_stream_session * session, const char * host, uint16_t port, int silent)
|
||||
{
|
||||
std::string remote(host);
|
||||
auto result = session->impl->forward(host, port, silent);
|
||||
|
||||
if(result.isOk) return 0;
|
||||
else return -1;
|
||||
}
|
||||
|
||||
const char * i2psam_namelookup(struct i2psam_stream_session * session, const char * name)
|
||||
{
|
||||
auto result = session->impl->namingLookup(name);
|
||||
|
||||
if(result.isOk) return strdup(result.value.c_str());
|
||||
else return nullptr;
|
||||
}
|
||||
|
||||
struct i2psam_destination * i2psam_dest_generate(struct i2psam_stream_session * session)
|
||||
{
|
||||
auto result = session->impl->destGenerate();
|
||||
if(result.isOk)
|
||||
{
|
||||
struct i2psam_destination * dest = new i2psam_destination;
|
||||
dest->pub = strdup(result.value.pub.c_str());
|
||||
dest->priv = strdup(result.value.priv.c_str());
|
||||
return dest;
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void i2psam_stop_forwarding(struct i2psam_stream_session * session, const char * host, uint16_t port)
|
||||
{
|
||||
session->impl->stopForwarding(host, port);
|
||||
}
|
||||
|
||||
void i2psam_stop_forwarding_all(struct i2psam_stream_session * session)
|
||||
{
|
||||
session->impl->stopForwardingAll();
|
||||
}
|
||||
|
||||
struct i2psam_destination * i2psam_get_my_destination(struct i2psam_stream_session * session)
|
||||
{
|
||||
struct i2psam_destination * dest = new i2psam_destination;
|
||||
const auto & mydest = session->impl->getMyDestination();
|
||||
dest->pub = strdup(mydest.pub.c_str());
|
||||
dest->priv = strdup(mydest.priv.c_str());
|
||||
return dest;
|
||||
}
|
||||
|
||||
void i2psam_write(struct i2psam_socket * sock, const char * data, size_t dlen)
|
||||
{
|
||||
const std::string buf(data, dlen);
|
||||
sock->impl->write(buf);
|
||||
}
|
||||
|
||||
char * i2psam_read(struct i2psam_socket * sock, size_t * dlen)
|
||||
{
|
||||
std::string buf = sock->impl->read();
|
||||
size_t sz = sizeof(char) * buf.size();
|
||||
*dlen = sz;
|
||||
if(sz)
|
||||
{
|
||||
char * ret = (char*) malloc(sz);
|
||||
memcpy(ret, buf.c_str(), sz);
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void i2psam_socket_close(struct i2psam_socket *sock)
|
||||
{
|
||||
sock->impl->close();
|
||||
}
|
||||
|
||||
int i2psam_socket_is_ok(struct i2psam_socket * sock)
|
||||
{
|
||||
if(sock->impl->isOk())
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void i2psam_socket_free(struct i2psam_socket * sock)
|
||||
{
|
||||
delete sock;
|
||||
}
|
||||
|
||||
const char * i2psam_destination_priv(struct i2psam_destination * dest)
|
||||
{
|
||||
return strdup(dest->priv);
|
||||
}
|
||||
|
||||
const char * i2psam_destination_pub(struct i2psam_destination * dest)
|
||||
{
|
||||
return strdup(dest->pub);
|
||||
}
|
||||
|
||||
void i2psam_destination_free(struct i2psam_destination * dest)
|
||||
{
|
||||
free(dest->pub);
|
||||
free(dest->priv);
|
||||
delete dest;
|
||||
}
|
||||
|
||||
}
|
||||
|
23
i2psam.h
23
i2psam.h
@ -8,14 +8,6 @@
|
||||
#ifndef I2PSAM_H
|
||||
#define I2PSAM_H
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <stdint.h>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#define SAM_DEFAULT_ADDRESS "127.0.0.1"
|
||||
#define SAM_DEFAULT_PORT 7656
|
||||
#define SAM_GENERATE_MY_DESTINATION "TRANSIENT"
|
||||
@ -47,7 +39,16 @@
|
||||
#define SAM_NAME_OUTBOUND_IPRESTRICTION "outbound.IPRestriction"
|
||||
#define SAM_DEFAULT_OUTBOUND_IPRESTRICTION 2
|
||||
#define SAM_NAME_OUTBOUND_PRIORITY "outbound.priority"
|
||||
#define SAM_DEFAULT_OUTBOUND_PRIORITY 0
|
||||
#define SAM_DEFAULT_OUTBOUND_PRIORITY
|
||||
|
||||
#ifdef __cplusplus // __cplusplus
|
||||
#include "compat.h"
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <stdint.h>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
namespace SAM
|
||||
{
|
||||
@ -400,4 +401,8 @@ private:
|
||||
|
||||
} // namespace SAM
|
||||
|
||||
|
||||
#else // __cplusplus
|
||||
#include "i2psam-c.h"
|
||||
#endif // __cplusplus
|
||||
#endif // I2PSAM_H
|
||||
|
Reference in New Issue
Block a user