41 Commits

Author SHA1 Message Date
idk
ebf7d0b012 Merge pull request #16 from i2p/generateKeys
fix public key out put in generateKeys
2020-12-13 13:51:33 +00:00
idk
b410da5986 add new examples/tests 2020-12-13 01:01:44 -05:00
idk
1b7b8cf8ba add new examples/tests 2020-12-13 01:00:46 -05:00
idk
9ca783a022 fix public key out put in generateKeys 2020-12-13 00:57:13 -05:00
idk
8623304b62 FORWARD is different from CONNECT and ACCEPT (#14) 2020-11-24 18:12:26 +00:00
idk
3f14a30065 clang-fmt 2020-11-24 13:12:07 -05:00
idk
ce0d1bfdfa FORWARD is different from CONNECT and ACCEPT 2020-11-24 13:09:52 -05:00
idk
749519ab1f Merge pull request #13 from i2p/remember-c
don't check for a correct reply on silent sessions
2020-11-24 17:43:46 +00:00
idk
a04bb557c7 don't check for a correct reply 2020-11-24 12:38:20 -05:00
idk
4bcaa17adb Merge pull request #12 from i2p/remember-c
do the checkIsSilent better
2020-11-24 17:15:18 +00:00
idk
ca20286c6b do the checkIsSilent better 2020-11-24 12:01:34 -05:00
idk
0aebf5a20a Merge pull request #11 from i2p/remember-c
Fix initialization of 'silent' *char
2020-11-23 23:28:08 +00:00
idk
baf1b3e580 clang-fmt 2020-11-23 15:01:07 -05:00
idk
e6b8f5e231 No, it needs to me a regular array not a string literal 2020-11-23 15:00:19 -05:00
idk
b324eb1e21 add examples to test silent sessions 2020-11-23 14:53:23 -05:00
idk
610e6c106e Fix initialization of 'silent' *char 2020-11-23 14:39:00 -05:00
idk
03ccfe263b Merge pull request #9 from i2p/windows-libsam3
Adds support for Windows to both libsam and libsam3a.
2020-11-20 19:42:51 +00:00
idk
20719276ec One last fix for the ssize_t define on Unixes 2020-11-20 11:58:47 -05:00
idk
f452e2729f Add some notes about the linker and our library users to the README.md 2020-11-20 11:53:26 -05:00
idk
92a33c892a Adjust how we define SOCK_CLOEXEC and SOCK_NONBLOCK on Windows 2020-11-20 11:31:59 -05:00
idk
4bf14d38e1 Make libsam3a compile on Windows, but seek clarity about if this is the correct approach tomorrow 2020-11-20 00:53:21 -05:00
idk
7f8e2b1082 fmt, add cross-compilind docs README.md 2020-11-18 15:13:57 -05:00
idk
f1a0559821 fmt, add cross-compilind docs README.md 2020-11-18 15:02:44 -05:00
idk
af7803c6fe define ssize_t on Windows ourselves 2020-11-18 14:56:00 -05:00
idk
e37c273913 define ssize_t on Windows ourselves 2020-11-18 13:12:14 -05:00
idk
c635aa4f6c define ssize_t on Windows ourselves 2020-11-18 12:26:15 -05:00
idk
49286ea282 This should add Windows support to libsam3, but **NOT** libsam3a 2020-11-18 11:41:26 -05:00
idk
4ed9b483fb Merge branch 'master' of https://github.com/i2p/libsam3 2020-11-18 11:39:52 -05:00
idk
83866763b8 Merge pull request #8 from eyedeekay/certfix
New Signature Types for Destinations
2020-11-17 16:36:49 +00:00
idk
c5a0504d12 Merge pull request #4 from eyedeekay/certfix
Certfix
2020-11-17 16:22:12 +00:00
idk
d88d7a17e3 Merge pull request #3 from eyedeekay/silent
Add a function to start a silent session instead of a regular session
2020-11-17 16:16:49 +00:00
idk
3c5e640c07 Merge branch 'certfix' into silent 2020-11-17 16:15:20 +00:00
idk
4436a53403 Merge pull request #2 from sehraf/certfix
WIP: Correct usage of SAM3_PRIVKEY_MIN_SIZE and enable library users to set SILENT=True
2020-11-17 16:13:19 +00:00
idk
796133ec42 Add a function to start a silent session instead of a regular session 2020-11-17 11:08:05 -05:00
sehraf
42ded33337 add SILENT=true to FORWARD 2020-10-26 19:14:36 +01:00
sehraf
eee8271b19 fix usage of SAM3_PRIVKEY_MIN_SIZE 2020-04-30 19:05:28 +02:00
idk
f61607e267 Merge branch 'master' of github.com:eyedeekay/libsam3 into certfix 2019-02-13 22:33:21 -05:00
idk
b3a700edeb Remove that clunky function and replace it 2019-02-13 22:30:19 -05:00
idk
5aebfd9116 Use connection 2019-02-13 21:30:41 -05:00
idk
933754748c Enable destination signatures 2019-02-13 21:13:27 -05:00
idk
cbcefc71c4 corrected the sample code and made them easier to build 2019-02-13 21:13:05 -05:00
14 changed files with 461 additions and 69 deletions

13
.gitignore vendored
View File

@@ -1,3 +1,14 @@
*.o
libsam3-tests
*.a
*.a
examples/libsam3
examples/sam3/dgrams
examples/sam3/dgramc
examples/sam3/keys
examples/sam3/keysp
examples/sam3namelookup
examples/sam3/streamss
examples/sam3/streamcs
examples/sam3/log
examples/sam3/err

View File

@@ -16,7 +16,6 @@ OBJS := ${LIB_OBJS} ${TEST_OBJS}
LIB := libsam3.a
all: build check
check: libsam3-tests
@@ -34,8 +33,11 @@ clean:
rm -f libsam3-tests ${LIB} ${OBJS} examples/sam3/samtest
%.o: %.c Makefile
${CC} ${CFLAGS} -c $< -o $@
${CC} ${CFLAGS} $(LDFLAGS) -c $< -o $@
fmt:
find . -name '*.c' -exec clang-format -i {} \;
find . -name '*.h' -exec clang-format -i {} \;
info:
@echo $(AR)

View File

@@ -6,7 +6,7 @@ A C library for the [SAM v3 API](https://geti2p.net/en/docs/api/samv3).
## Development Status
Unmaintained, but PRs welcome!
Maintained by idk, PRs are accepted on [I2P gitlab](https://i2pgit.org/i2p-hackers/libsam3)/[I2P gitlab](http://git.idk.i2p/i2p-hackers/libsam3), and on github at the official mirror repository: [i2p/libsam3](https://github.com/i2p/libsam3).
## Usage
@@ -16,3 +16,37 @@ Copy the two files from one of the following locations into your codebase:
- `src/libsam3a` - Asynchronous implementation.
See `examples/` for how to use various parts of the API.
## Cross-Compiling for Windows from debian:
Set your cross-compiler up:
``` sh
export CC=x86_64-w64-mingw32-gcc
export CFLAGS='-Wall -O2 '
export LDFLAGS='-lmingw32 -lws2_32 -lwsock32 -mwindows'
```
and run `make build`. Only libsam3 is available for Windows, libsam3a will be
made available at a later date.
`
## Linker(Windows)
When building for Windows remember to set the flags to link to the Winsock and Windows
libraries.
`-lmingw32 -lws2_32 -lwsock32 -mwindows`
This may apply when cross-compiling or compiling from Windows with mingw.
## Cool Projects using libsam3
Are you using libsam3 to provide an a cool I2P based feature to your project? Let us know about it(and how
it uses libsam3) and we'll think about adding it here*!
1. [Retroshare](https://retroshare.cc)
*Projects which are listed here must be actively maintained. Those which intentionally violate
the law or the rights of a person or persons directly won't be considered. Neither will obvious
trolling. The maintainer will make the final decision.

1
examples/libsam3 Symbolic link
View File

@@ -0,0 +1 @@
../src/libsam3

44
examples/sam3/Makefile Normal file
View File

@@ -0,0 +1,44 @@
CFLAGS := -Wall -g -O2 -std=gnu99
all: clean examples
examples: example lookup dclient dserver sclient sserver ssserver ssclient
example:
${CC} ${CFLAGS} samtest.c -o samtest ../libsam3/libsam3.o
lookup:
${CC} ${CFLAGS} namelookup.c -o lookup ../libsam3/libsam3.o
dclient:
${CC} ${CFLAGS} dgramc.c -o dgramc ../libsam3/libsam3.o
dserver:
${CC} ${CFLAGS} dgrams.c -o dgrams ../libsam3/libsam3.o
sclient:
${CC} ${CFLAGS} streamc.c -o streamc ../libsam3/libsam3.o
sserver:
${CC} ${CFLAGS} streams.c -o streams ../libsam3/libsam3.o
ssclient:
${CC} ${CFLAGS} streamcs.c -o streamcs ../libsam3/libsam3.o
ssserver:
${CC} ${CFLAGS} streamss.c -o streamss ../libsam3/libsam3.o
keysp:
${CXX} ${CFLAGS} keys.cc -o keysp ../libsam3/libsam3.o
keys:
${CC} ${CFLAGS} keys.c -o keys ../libsam3/libsam3.o
clean:
rm -f samtest lookup dgramc dgrams streamc streams streams.key test-lookup keys keysp
debug:
sed -i 's|// libsam3_debug = 1;|libsam3_debug = 1;|g' *.c
nodebug:
sed -i 's|libsam3_debug = 1;|// libsam3_debug = 1;|g' *.c

26
examples/sam3/README.md Normal file
View File

@@ -0,0 +1,26 @@
Examples
========
These examples show various ways of using libsam3 to enable i2p in your
application, and are also useful in other ways. If you implement an i2p
application library in another language, making variants basic tools wouldn't be
the worst way to make sure that it works.
building
--------
Once you have build the library in the root of this repository by running make
all, you can build all these examples at once by running
make
in this directory. I think it makes things easier to experiment with quickly.
namelookup
----------
Namelookup uses the SAM API to find the base64 destination of an readable "jump"
or base32 i2p address. You can use it like this:
./lookup i2p-projekt.i2p

20
examples/sam3/keys.c Normal file
View File

@@ -0,0 +1,20 @@
//#include <string>
//#include <iostream>
#include "../libsam3/libsam3.h"
#include <stdio.h>
int main() {
// The session is only usef for transporting the data
Sam3Session ss;
if (0 > sam3GenerateKeys(&ss, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, 4)) {
printf("got error");
return -1;
}
printf("\tpubkey: %s \n \tprivkey: %s", ss.pubkey, ss.privkey);
/*auto pub = std::string(ss.pubkey);
auto priv = std::string(ss.privkey);
std::cout << "pub " << pub << std::endl << "priv " << priv << std::endl;*/
return 0;
}

19
examples/sam3/keys.cc Normal file
View File

@@ -0,0 +1,19 @@
#include <string>
#include <iostream>
#include <stdio.h>
#include "../libsam3/libsam3.h"
int main() {
// The session is only usef for transporting the data
Sam3Session ss;
if (0 > sam3GenerateKeys(&ss, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, Sam3SigType::EdDSA_SHA512_Ed25519)) {
printf("got error");
return -1;
}
auto pub = std::string(ss.pubkey);
auto priv = std::string(ss.privkey);
std::cout << "pub " << pub << std::endl << "priv " << priv << std::endl;
return 0;
}

87
examples/sam3/streamcs.c Normal file
View File

@@ -0,0 +1,87 @@
/* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*
* I2P-Bote:
* 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV
* we are the Borg. */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "../libsam3/libsam3.h"
#define KEYFILE "streams.key"
int main(int argc, char *argv[]) {
Sam3Session ses;
Sam3Connection *conn;
char cmd[1024], destkey[617]; // 616 chars + \0
//
libsam3_debug = 1;
//
memset(destkey, 0, sizeof(destkey));
//
if (argc < 2) {
FILE *fl = fopen(KEYFILE, "rb");
//
if (fl != NULL) {
if (fread(destkey, 616, 1, fl) == 1) {
fclose(fl);
goto ok;
}
fclose(fl);
}
printf("usage: streamc PUBKEY\n");
return 1;
} else {
if (!sam3CheckValidKeyLength(argv[1])) {
fprintf(stderr, "FATAL: invalid key length! %s %lu\n", argv[1],
strlen(argv[1]));
return 1;
}
strcpy(destkey, argv[1]);
}
//
ok:
printf("creating session...\n");
// create TRANSIENT session
if (sam3CreateSilentSession(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT,
SAM3_DESTINATION_TRANSIENT, SAM3_SESSION_STREAM,
4, NULL) < 0) {
fprintf(stderr, "FATAL: can't create session\n");
return 1;
}
//
printf("connecting...\n");
if ((conn = sam3StreamConnect(&ses, destkey)) == NULL) {
fprintf(stderr, "FATAL: can't connect: %s\n", ses.error);
sam3CloseSession(&ses);
return 1;
}
//
// now waiting for incoming connection
printf("sending test command...\n");
if (sam3tcpPrintf(conn->fd, "test\n") < 0)
goto error;
if (sam3tcpReceiveStr(conn->fd, cmd, sizeof(cmd)) < 0)
goto error;
printf("echo: %s\n", cmd);
//
printf("sending quit command...\n");
if (sam3tcpPrintf(conn->fd, "quit\n") < 0)
goto error;
//
sam3CloseConnection(conn);
sam3CloseSession(&ses);
return 0;
error:
fprintf(stderr, "FATAL: some error occured!\n");
sam3CloseConnection(conn);
sam3CloseSession(&ses);
return 1;
}

72
examples/sam3/streamss.c Normal file
View File

@@ -0,0 +1,72 @@
/* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*
* I2P-Bote:
* 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV
* we are the Borg. */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "../libsam3/libsam3.h"
#define KEYFILE "streams.key"
int main(int argc, char *argv[]) {
Sam3Session ses;
Sam3Connection *conn;
FILE *fl;
//
libsam3_debug = 1;
//
printf("creating session...\n");
// create TRANSIENT session
if (sam3CreateSilentSession(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT,
SAM3_DESTINATION_TRANSIENT, SAM3_SESSION_STREAM,
4, NULL) < 0) {
fprintf(stderr, "FATAL: can't create session\n");
return 1;
}
//
printf("PUB KEY\n=======\n%s\n=======\n", ses.pubkey);
if ((fl = fopen(KEYFILE, "wb")) != NULL) {
fwrite(ses.pubkey, strlen(ses.pubkey), 1, fl);
fclose(fl);
}
//
printf("starting stream acceptor...\n");
if ((conn = sam3StreamAccept(&ses)) == NULL) {
fprintf(stderr, "FATAL: can't accept: %s\n", ses.error);
sam3CloseSession(&ses);
return 1;
}
printf("FROM\n====\n%s\n====\n", conn->destkey);
//
printf("starting main loop...\n");
for (;;) {
char cmd[256];
//
if (sam3tcpReceiveStr(conn->fd, cmd, sizeof(cmd)) < 0)
goto error;
printf("cmd: [%s]\n", cmd);
if (strcmp(cmd, "quit") == 0)
break;
// echo command
if (sam3tcpPrintf(conn->fd, "re: %s\n", cmd) < 0)
goto error;
}
//
sam3CloseSession(&ses);
unlink(KEYFILE);
return 0;
error:
fprintf(stderr, "FATAL: some error occured!\n");
sam3CloseSession(&ses);
unlink(KEYFILE);
return 1;
}

View File

@@ -11,7 +11,6 @@
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
@@ -20,20 +19,30 @@
#include <time.h>
#include <unistd.h>
#ifdef __MINGW32__
//#include <winsock.h>
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0
#endif
#ifndef SHUT_RDWR
#define SHUT_RDWR 2
#endif
#endif
#ifdef __unix__
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/sysinfo.h>
#include <sys/types.h>
#ifdef WINDOWS_SYS
#include <winsock.h>
#endif // WINDOWS_SYS
#endif
////////////////////////////////////////////////////////////////////////////////
int libsam3_debug = 0;
////////////////////////////////////////////////////////////////////////////////
/* convert struct timeval to milliseconds */
/*
@@ -105,11 +114,6 @@ int sam3tcpConnectIP(uint32_t ip, int port) {
}
}
//
// Set this for all outgoing SAM connections. Most SAM commands should be answered rather fast except CREATE SESSION maybe.
// This should be enough to let SAM establish a session.
sam3tcpSetTimeoutSend(fd, 5 * 60 * 1000);
sam3tcpSetTimeoutReceive(fd, 5 * 60 * 1000);
//
setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val));
//
if (connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) {
@@ -162,13 +166,8 @@ int sam3tcpConnect(const char *hostname, int port, uint32_t *ip) {
// <0: error; 0: ok
int sam3tcpDisconnect(int fd) {
if (fd >= 0) {
#ifndef WINDOWS_SYS // ie UNIX
shutdown(fd, SHUT_RDWR);
return close(fd);
#else
return closesocket(fd);
#endif
shutdown(fd, SHUT_RDWR);
return close(fd);
}
//
return -1;
@@ -560,7 +559,6 @@ int sam3IsGoodReply(const SAMFieldList *list, const char *r0, const char *r1,
return 0;
}
////////////////////////////////////////////////////////////////////////////////
// by Bob Jenkins
// public domain
@@ -718,20 +716,23 @@ int sam3GenerateKeys(Sam3Session *ses, const char *hostname, int port,
return -1;
}
//
if (sam3tcpPrintf(fd, "DEST GENERATE %s\n", sigtypes[sigType]) >= 0) {
if ((rep = sam3ReadReply(fd)) != NULL &&
sam3IsGoodReply(rep, "DEST", "REPLY", NULL, NULL)) {
const char *pub = sam3FindField(rep, "PUB"),
*priv = sam3FindField(rep, "PRIV");
//
if (pub != NULL && sam3CheckValidKeyLength(pub) && priv != NULL &&
strlen(priv) >= SAM3_PRIVKEY_MIN_SIZE) {
strcpy(ses->pubkey, pub);
strcpy(ses->privkey, priv);
res = 0;
}
}
if (sam3tcpPrintf(fd, "DEST GENERATE\n") < 0) {
strcpyerr(ses, "DEST_ERROR");
}
rep = sam3ReadReply(fd);
// sam3DumpFieldList(rep);
if (!sam3IsGoodReply(rep, "DEST", "REPLY", "PUB", NULL)) {
strcpyerr(ses, "PUBKEY_ERROR");
}
if (!sam3IsGoodReply(rep, "DEST", "REPLY", "PRIV", NULL)) {
strcpyerr(ses, "PRIVKEY_ERROR");
}
const char *pub = sam3FindField(rep, "PUB");
strcpy(ses->pubkey, pub);
const char *priv = sam3FindField(rep, "PRIV");
strcpy(ses->privkey, priv);
res = 0;
//
sam3FreeFieldList(rep);
sam3tcpDisconnect(fd);
@@ -825,6 +826,18 @@ int sam3CloseSession(Sam3Session *ses) {
return -1;
}
int sam3CreateSilentSession(Sam3Session *ses, const char *hostname, int port,
const char *privkey, Sam3SessionType type,
Sam3SigType sigType, const char *params) {
int r =
sam3CreateSession(ses, hostname, port, privkey, type, sigType, params);
if (r != 0) {
return r;
}
ses->silent = true;
return 0;
}
int sam3CreateSession(Sam3Session *ses, const char *hostname, int port,
const char *privkey, Sam3SessionType type,
Sam3SigType sigType, const char *params) {
@@ -842,6 +855,7 @@ int sam3CreateSession(Sam3Session *ses, const char *hostname, int port,
memset(ses, 0, sizeof(Sam3Session));
ses->fd = -1;
ses->fwd_fd = -1;
ses->silent = false;
//
if (privkey != NULL && strlen(privkey) < SAM3_PRIVKEY_MIN_SIZE)
goto error;
@@ -938,8 +952,9 @@ Sam3Connection *sam3StreamConnect(Sam3Session *ses, const char *destkey) {
strcpyerr(ses, "IO_ERROR_SK");
goto error;
}
if (sam3tcpPrintf(conn->fd, "STREAM CONNECT ID=%s DESTINATION=%s\n",
ses->channel, destkey) < 0) {
if (sam3tcpPrintf(conn->fd,
"STREAM CONNECT ID=%s DESTINATION=%s SILENT=%s\n",
ses->channel, destkey, checkIsSilent(ses)) < 0) {
strcpyerr(ses, "IO_ERROR");
goto error;
}
@@ -947,16 +962,18 @@ Sam3Connection *sam3StreamConnect(Sam3Session *ses, const char *destkey) {
strcpyerr(ses, "IO_ERROR");
goto error;
}
if (!sam3IsGoodReply(rep, "STREAM", "STATUS", "RESULT", "OK")) {
const char *v = sam3FindField(rep, "RESULT");
//
strcpyerr(ses, (v != NULL && v[0] ? v : "I2P_ERROR"));
sam3CloseConnectionInternal(conn);
free(conn);
conn = NULL;
} else {
// no error
strcpyerr(ses, NULL);
if (!ses->silent) {
if (!sam3IsGoodReply(rep, "STREAM", "STATUS", "RESULT", "OK")) {
const char *v = sam3FindField(rep, "RESULT");
//
strcpyerr(ses, (v != NULL && v[0] ? v : "I2P_ERROR"));
sam3CloseConnectionInternal(conn);
free(conn);
conn = NULL;
} else {
// no error
strcpyerr(ses, NULL);
}
}
sam3FreeFieldList(rep);
if (conn != NULL) {
@@ -1004,11 +1021,13 @@ Sam3Connection *sam3StreamAccept(Sam3Session *ses) {
strcpyerr(ses, "IO_ERROR_RP");
goto error;
}
if (!sam3IsGoodReply(rep, "STREAM", "STATUS", "RESULT", "OK")) {
const char *v = sam3FindField(rep, "RESULT");
//
strcpyerr(ses, (v != NULL && v[0] ? v : "I2P_ERROR_RES"));
goto error;
if (!ses->silent) {
if (!sam3IsGoodReply(rep, "STREAM", "STATUS", "RESULT", "OK")) {
const char *v = sam3FindField(rep, "RESULT");
//
strcpyerr(ses, (v != NULL && v[0] ? v : "I2P_ERROR_RES"));
goto error;
}
}
if (sam3tcpReceiveStr(conn->fd, repstr, sizeof(repstr)) < 0) {
strcpyerr(ses, "IO_ERROR_RP1");
@@ -1042,6 +1061,14 @@ Sam3Connection *sam3StreamAccept(Sam3Session *ses) {
return NULL;
}
const char *checkIsSilent(Sam3Session *ses) {
if (ses->silent == true) {
return "true";
} else {
return "false";
}
}
int sam3StreamForward(Sam3Session *ses, const char *hostname, int port) {
if (ses != NULL) {
SAMFieldList *rep = NULL;
@@ -1062,8 +1089,9 @@ int sam3StreamForward(Sam3Session *ses, const char *hostname, int port) {
strcpyerr(ses, "IO_ERROR_SK");
goto error;
}
if (sam3tcpPrintf(ses->fwd_fd, "STREAM FORWARD ID=%s PORT=%d HOST=%s SILENT=true\n",
ses->channel, port, hostname) < 0) {
if (sam3tcpPrintf(ses->fwd_fd,
"STREAM FORWARD ID=%s PORT=%d HOST=%s SILENT=%s\n",
ses->channel, port, hostname, checkIsSilent(ses)) < 0) {
strcpyerr(ses, "IO_ERROR_PF");
goto error;
}

View File

@@ -10,14 +10,23 @@
#ifndef LIBSAM3_H
#define LIBSAM3_H
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#ifndef _SSIZE_T_DEFINED
#define _SSIZE_T_DEFINED
#undef ssize_t
#ifdef _WIN64
typedef signed int64 ssize_t;
typedef int ssize_t;
#endif /* _WIN64 */
#endif /* _SSIZE_T_DEFINED */
#ifdef __cplusplus
extern "C" {
#endif
////////////////////////////////////////////////////////////////////////////////
extern int libsam3_debug;
@@ -139,6 +148,7 @@ typedef struct Sam3Session {
int port; // this will be changed to UDP port for DRAM/RAW (can be 0)
struct Sam3Connection *connlist; // list of opened connections
int fwd_fd;
bool silent;
} Sam3Session;
typedef struct Sam3Connection {
@@ -151,7 +161,6 @@ typedef struct Sam3Connection {
char error[32]; // error message (asciiz)
} Sam3Connection;
////////////////////////////////////////////////////////////////////////////////
/*
* create SAM session
@@ -168,6 +177,22 @@ extern int sam3CreateSession(Sam3Session *ses, const char *hostname, int port,
const char *privkey, Sam3SessionType type,
Sam3SigType sigType, const char *params);
/*
* create SAM session with SILENT=True
* pass NULL as hostname for 'localhost' and 0 as port for 7656
* pass NULL as privkey to create TRANSIENT session
* 'params' can be NULL
* see http://www.i2p2.i2p/i2cp.html#options for common options,
* and http://www.i2p2.i2p/streaming.html#options for STREAM options
* if result<0: error, 'ses' fields are undefined, no need to call
* sam3CloseSession() if result==0: ok, all 'ses' fields are filled
* TODO: don't clear 'error' field on error (and set it to something meaningful)
*/
extern int sam3CreateSilentSession(Sam3Session *ses, const char *hostname,
int port, const char *privkey,
Sam3SessionType type, Sam3SigType sigType,
const char *params);
/*
* close SAM session (and all it's connections)
* returns <0 on error, 0 on ok
@@ -175,6 +200,13 @@ extern int sam3CreateSession(Sam3Session *ses, const char *hostname, int port,
*/
extern int sam3CloseSession(Sam3Session *ses);
/*
* check to see if a SAM session is silent and output
* characters for use with sam3tcpPrintf() checkIsSilent
*/
const char *checkIsSilent(Sam3Session *ses);
/*
* Check to make sure that the destination in use is of a valid length, returns
* 1 if true and 0 if false.

View File

@@ -13,7 +13,6 @@
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
@@ -22,13 +21,28 @@
#include <time.h>
#include <unistd.h>
#ifdef __MINGW32__
//#include <winsock.h>
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0
#endif
#ifndef SHUT_RDWR
#define SHUT_RDWR 2
#endif
#endif
#ifdef __unix__
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/sysinfo.h>
#include <sys/types.h>
#endif
////////////////////////////////////////////////////////////////////////////////
int libsam3a_debug = 0;
@@ -71,7 +85,6 @@ int sam3aIsValidPrivKey(const char *key) {
return 0;
}
////////////////////////////////////////////////////////////////////////////////
/*
static int sam3aSocketSetTimeoutSend (int fd, int timeoutms) {
@@ -342,7 +355,6 @@ static int sam3aCheckEOL (int fd, int bytes2check) {
}
*/
////////////////////////////////////////////////////////////////////////////////
/*
int sam3audpSendToIP (uint32_t ip, int port, const void *buf, int bufSize) {
@@ -399,7 +411,6 @@ bufSize);
}
*/
////////////////////////////////////////////////////////////////////////////////
typedef struct SAMFieldList {
char *name;
@@ -587,7 +598,6 @@ SAMFieldList *sam3aReadReply (int fd) {
}
*/
////////////////////////////////////////////////////////////////////////////////
// by Bob Jenkins
// public domain

View File

@@ -18,18 +18,27 @@
#include <sys/types.h>
#ifdef __MINGW32__
//#include <winsock.h>
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
//#define SOCK_CLOEXEC O_CLOEXEC
//#define SOCK_NONBLOCK O_NONBLOCK
#define SOCK_CLOEXEC 02000000
#define SOCK_NONBLOCK FIONBIO
#endif
#ifdef __cplusplus
extern "C" {
#endif
////////////////////////////////////////////////////////////////////////////////
/*
* TODO:
* [.] block sam3aClose*() in callbacks
*/
////////////////////////////////////////////////////////////////////////////////
extern int libsam3a_debug;
@@ -54,14 +63,12 @@ extern int sam3aIsValidPrivKey(const char *key);
typedef struct Sam3ASession Sam3ASession;
typedef struct Sam3AConnection Sam3AConnection;
typedef enum {
SAM3A_SESSION_RAW,
SAM3A_SESSION_DGRAM,
SAM3A_SESSION_STREAM
} Sam3ASessionType;
typedef struct {
char *data;
int dataSize;
@@ -337,7 +344,6 @@ static inline int sam3aNameLookup(Sam3ASession *ses,
return sam3aNameLookupEx(ses, cb, hostname, port, name, -1);
}
////////////////////////////////////////////////////////////////////////////////
/*
* append session fd to read and write sets if necessary