1 Commits

19 changed files with 2252 additions and 1742 deletions

View File

@@ -31,7 +31,11 @@ libsam3-tests: ${TEST_OBJS} ${LIB}
${CC} $^ -o $@ ${CC} $^ -o $@
clean: clean:
rm -f libsam3-tests ${LIB} ${OBJS} rm -f libsam3-tests ${LIB} ${OBJS} examples/sam3/samtest
%.o: %.c Makefile %.o: %.c Makefile
${CC} ${CFLAGS} -c $< -o $@ ${CC} ${CFLAGS} -c $< -o $@
fmt:
find . -name '*.c' -exec clang-format -i {} \;
find . -name '*.h' -exec clang-format -i {} \;

View File

@@ -4,7 +4,8 @@
* To Public License, Version 2, as published by Sam Hocevar. See * To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details. * http://sam.zoy.org/wtfpl/COPYING for more details.
* *
* I2P-Bote: 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV * I2P-Bote:
* 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV
* we are the Borg. */ * we are the Borg. */
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
@@ -14,23 +15,20 @@
#include "../libsam3/libsam3.h" #include "../libsam3/libsam3.h"
// comment the following if you don't want to stress UDP with 'big' datagram // comment the following if you don't want to stress UDP with 'big' datagram
// seems that up to 32000 bytes can be used for localhost // seems that up to 32000 bytes can be used for localhost
// note that we need 516+6+? bytes for header; lets reserve 1024 bytes for it // note that we need 516+6+? bytes for header; lets reserve 1024 bytes for it
#define BIG (32000-1024) #define BIG (32000 - 1024)
#define KEYFILE "dgrams.key" #define KEYFILE "dgrams.key"
int main(int argc, char *argv[]) {
int main (int argc, char *argv[]) {
Sam3Session ses; Sam3Session ses;
char buf[1024]; char buf[1024];
char destkey[517] = {0}; // 516 chars + \0 char destkey[517] = {0}; // 516 chars + \0
int sz; int sz;
// //
//libsam3_debug = 1; libsam3_debug = 1;
// //
if (argc < 2) { if (argc < 2) {
FILE *fl = fopen(KEYFILE, "rb"); FILE *fl = fopen(KEYFILE, "rb");
@@ -55,7 +53,9 @@ int main (int argc, char *argv[]) {
ok: ok:
printf("creating session...\n"); printf("creating session...\n");
/* create TRANSIENT session with temporary disposible destination */ /* create TRANSIENT session with temporary disposible destination */
if (sam3CreateSession(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, SAM3_DESTINATION_TRANSIENT, SAM3_SESSION_DGRAM, NULL) < 0) { if (sam3CreateSession(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT,
SAM3_DESTINATION_TRANSIENT, SAM3_SESSION_DGRAM, 4,
NULL) < 0) {
fprintf(stderr, "FATAL: can't create session\n"); fprintf(stderr, "FATAL: can't create session\n");
return 1; return 1;
} }
@@ -66,7 +66,7 @@ ok:
goto error; goto error;
} }
/** receive reply */ /** receive reply */
if ((sz = sam3DatagramReceive(&ses, buf, sizeof(buf)-1)) < 0) { if ((sz = sam3DatagramReceive(&ses, buf, sizeof(buf) - 1)) < 0) {
fprintf(stderr, "ERROR: %s\n", ses.error); fprintf(stderr, "ERROR: %s\n", ses.error);
goto error; goto error;
} }
@@ -76,16 +76,16 @@ ok:
// //
#ifdef BIG #ifdef BIG
{ {
char *big = calloc(BIG+1024, sizeof(char)); char *big = calloc(BIG + 1024, sizeof(char));
/** generate random string */ /** generate random string */
sam3GenChannelName(big, BIG+1023, BIG+1023); sam3GenChannelName(big, BIG + 1023, BIG + 1023);
printf("sending BIG datagram...\n"); printf("sending BIG datagram...\n");
if (sam3DatagramSend(&ses, destkey, big, BIG) < 0) { if (sam3DatagramSend(&ses, destkey, big, BIG) < 0) {
free(big); free(big);
fprintf(stderr, "ERROR: %s\n", ses.error); fprintf(stderr, "ERROR: %s\n", ses.error);
goto error; goto error;
} }
if ((sz = sam3DatagramReceive(&ses, big, BIG+512)) < 0) { if ((sz = sam3DatagramReceive(&ses, big, BIG + 512)) < 0) {
free(big); free(big);
fprintf(stderr, "ERROR: %s\n", ses.error); fprintf(stderr, "ERROR: %s\n", ses.error);
goto error; goto error;
@@ -101,7 +101,7 @@ ok:
fprintf(stderr, "ERROR: %s\n", ses.error); fprintf(stderr, "ERROR: %s\n", ses.error);
goto error; goto error;
} }
if ((sz = sam3DatagramReceive(&ses, buf, sizeof(buf)-1)) < 0) { if ((sz = sam3DatagramReceive(&ses, buf, sizeof(buf) - 1)) < 0) {
fprintf(stderr, "ERROR: %s\n", ses.error); fprintf(stderr, "ERROR: %s\n", ses.error);
goto error; goto error;
} }

View File

@@ -4,7 +4,8 @@
* To Public License, Version 2, as published by Sam Hocevar. See * To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details. * http://sam.zoy.org/wtfpl/COPYING for more details.
* *
* I2P-Bote: 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV * I2P-Bote:
* 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV
* we are the Borg. */ * we are the Borg. */
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
@@ -14,31 +15,28 @@
#include "../libsam3/libsam3.h" #include "../libsam3/libsam3.h"
#define KEYFILE "dgrams.key" #define KEYFILE "dgrams.key"
int main(int argc, char *argv[]) {
int main (int argc, char *argv[]) {
Sam3Session ses; Sam3Session ses;
char privkey[1024], pubkey[1024], buf[33*1024]; char privkey[1024], pubkey[1024], buf[33 * 1024];
/** quit command */ /** quit command */
const char * quitstr = "quit"; const char *quitstr = "quit";
const size_t quitlen = strlen(quistr); const size_t quitlen = strlen(quitstr);
/** reply response */ /** reply response */
const char * replystr = "reply: "; const char *replystr = "reply: ";
const size_t replylen = strlen(replystr); const size_t replylen = strlen(replystr);
FILE *fl; FILE *fl;
// //
//libsam3_debug = 1; libsam3_debug = 1;
// //
/** generate new destination keypair */ /** generate new destination keypair */
printf("generating keys...\n"); printf("generating keys...\n");
if (sam3GenerateKeys(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT) < 0) { if (sam3GenerateKeys(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, 4) < 0) {
fprintf(stderr, "FATAL: can't generate keys\n"); fprintf(stderr, "FATAL: can't generate keys\n");
return 1; return 1;
} }
@@ -47,7 +45,8 @@ int main (int argc, char *argv[]) {
strncpy(privkey, ses.privkey, sizeof(privkey)); strncpy(privkey, ses.privkey, sizeof(privkey));
/** create sam session */ /** create sam session */
printf("creating session...\n"); printf("creating session...\n");
if (sam3CreateSession(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, privkey, SAM3_SESSION_DGRAM, NULL) < 0) { if (sam3CreateSession(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, privkey,
SAM3_SESSION_DGRAM, 5, NULL) < 0) {
fprintf(stderr, "FATAL: can't create session\n"); fprintf(stderr, "FATAL: can't create session\n");
return 1; return 1;
} }
@@ -70,12 +69,12 @@ int main (int argc, char *argv[]) {
printf("starting main loop...\n"); printf("starting main loop...\n");
for (;;) { for (;;) {
/** save replylen bytes for out reply at begining */ /** save replylen bytes for out reply at begining */
char * datagramBuf = buf + replylen; char *datagramBuf = buf + replylen;
const size_t datagramMaxLen = sizeof(buf) - replyLen; const size_t datagramMaxLen = sizeof(buf) - replylen;
int sz, isquit; int sz, isquit;
printf("waiting for datagram...\n"); printf("waiting for datagram...\n");
/** blocks until we get a UDP packet */ /** blocks until we get a UDP packet */
if ((sz = sam3DatagramReceive(&ses, datagramBuf, datagarmMaxLen) < 0)) { if ((sz = sam3DatagramReceive(&ses, datagramBuf, datagramMaxLen) < 0)) {
fprintf(stderr, "ERROR: %s\n", ses.error); fprintf(stderr, "ERROR: %s\n", ses.error);
goto error; goto error;
} }
@@ -90,11 +89,12 @@ int main (int argc, char *argv[]) {
/** echo datagram back to sender with "reply: " at the beginning */ /** echo datagram back to sender with "reply: " at the beginning */
memcpy(buf, replystr, replylen); memcpy(buf, replystr, replylen);
if (sam3DatagramSend(&ses, ses.destkey, buf, sz+replylen) < 0) { if (sam3DatagramSend(&ses, ses.destkey, buf, sz + replylen) < 0) {
fprintf(stderr, "ERROR: %s\n", ses.error); fprintf(stderr, "ERROR: %s\n", ses.error);
goto error; goto error;
} }
/** if we got a quit command wait for 10 seconds and break out of the mainloop */ /** if we got a quit command wait for 10 seconds and break out of the
* mainloop */
if (isquit) { if (isquit) {
printf("shutting down...\n"); printf("shutting down...\n");
sleep(10); /* let dgram reach it's destination */ sleep(10); /* let dgram reach it's destination */

View File

@@ -4,7 +4,8 @@
* To Public License, Version 2, as published by Sam Hocevar. See * To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details. * http://sam.zoy.org/wtfpl/COPYING for more details.
* *
* I2P-Bote: 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV * I2P-Bote:
* 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV
* we are the Borg. */ * we are the Borg. */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -13,19 +14,25 @@
#include "../libsam3/libsam3.h" #include "../libsam3/libsam3.h"
int main(int argc, char *argv[]) {
int main (int argc, char *argv[]) {
Sam3Session ses; Sam3Session ses;
// //
//
libsam3_debug = 1;
//
if (argc < 2) { if (argc < 2) {
printf("usage: %s name [name...]\n", argv[0]); printf("usage: %s name [name...]\n", argv[0]);
return 1; return 1;
} }
/** for each name in arguments ... */ /** for each name in arguments ... */
for (int n = 1; n < argc; ++n) { for (int n = 1; n < argc; ++n) {
fprintf(stdout, "%s ... ", argv[n]); fflush(stdout); if (!getenv("I2P_LOOKUP_QUIET")) {
fprintf(stdout, "%s ... ", argv[n]);
fflush(stdout);
}
/** do oneshot name lookup */ /** do oneshot name lookup */
if (sam3NameLookup(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, argv[n]) >= 0) { if (sam3NameLookup(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, argv[n]) >=
0) {
fprintf(stdout, "%s\n\n", ses.destkey); fprintf(stdout, "%s\n\n", ses.destkey);
} else { } else {
fprintf(stdout, "FAILED [%s]\n", ses.error); fprintf(stdout, "FAILED [%s]\n", ses.error);

View File

@@ -4,7 +4,8 @@
* To Public License, Version 2, as published by Sam Hocevar. See * To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details. * http://sam.zoy.org/wtfpl/COPYING for more details.
* *
* I2P-Bote: 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV * I2P-Bote:
* 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV
* we are the Borg. */ * we are the Borg. */
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
@@ -14,19 +15,25 @@
#include "../libsam3/libsam3.h" #include "../libsam3/libsam3.h"
int main(int argc, char *argv[]) {
int main (int argc, char *argv[]) {
int fd; int fd;
SAMFieldList *rep = NULL; SAMFieldList *rep = NULL;
const char *v; const char *v;
// //
if ((fd = sam3Handshake(NULL, 0, NULL)) < 0) return 1; libsam3_debug = 1;
// //
if (sam3tcpPrintf(fd, "DEST GENERATE\n") < 0) goto error; //
if ((fd = sam3Handshake(NULL, 0, NULL)) < 0)
return 1;
//
if (sam3tcpPrintf(fd, "DEST GENERATE\n") < 0)
goto error;
rep = sam3ReadReply(fd); rep = sam3ReadReply(fd);
//sam3DumpFieldList(rep); // sam3DumpFieldList(rep);
if (!sam3IsGoodReply(rep, "DEST", "REPLY", "PUB", NULL)) goto error; if (!sam3IsGoodReply(rep, "DEST", "REPLY", "PUB", NULL))
if (!sam3IsGoodReply(rep, "DEST", "REPLY", "PRIV", NULL)) goto error; goto error;
if (!sam3IsGoodReply(rep, "DEST", "REPLY", "PRIV", NULL))
goto error;
v = sam3FindField(rep, "PUB"); v = sam3FindField(rep, "PUB");
printf("PUB KEY\n=======\n%s\n", v); printf("PUB KEY\n=======\n%s\n", v);
v = sam3FindField(rep, "PRIV"); v = sam3FindField(rep, "PRIV");

View File

@@ -4,7 +4,8 @@
* To Public License, Version 2, as published by Sam Hocevar. See * To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details. * http://sam.zoy.org/wtfpl/COPYING for more details.
* *
* I2P-Bote: 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV * I2P-Bote:
* 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV
* we are the Borg. */ * we are the Borg. */
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
@@ -14,16 +15,14 @@
#include "../libsam3/libsam3.h" #include "../libsam3/libsam3.h"
#define KEYFILE "streams.key" #define KEYFILE "streams.key"
int main(int argc, char *argv[]) {
int main (int argc, char *argv[]) {
Sam3Session ses; Sam3Session ses;
Sam3Connection *conn; Sam3Connection *conn;
char cmd[1024], destkey[517]; // 516 chars + \0 char cmd[1024], destkey[617]; // 616 chars + \0
// //
//libsam3_debug = 1; libsam3_debug = 1;
// //
memset(destkey, 0, sizeof(destkey)); memset(destkey, 0, sizeof(destkey));
// //
@@ -31,17 +30,18 @@ int main (int argc, char *argv[]) {
FILE *fl = fopen(KEYFILE, "rb"); FILE *fl = fopen(KEYFILE, "rb");
// //
if (fl != NULL) { if (fl != NULL) {
if (fread(destkey, 516, 1, fl) == 1) { if (fread(destkey, 616, 1, fl) == 1) {
fclose(fl); fclose(fl);
goto ok; goto ok;
} }
fclose(fl); fclose(fl);
} }
printf("usage: dgramc PUBKEY\n"); printf("usage: streamc PUBKEY\n");
return 1; return 1;
} else { } else {
if (strlen(argv[1]) != 516) { if (!sam3CheckValidKeyLength(argv[1])) {
fprintf(stderr, "FATAL: invalid key length!\n"); fprintf(stderr, "FATAL: invalid key length! %s %lu\n", argv[1],
strlen(argv[1]));
return 1; return 1;
} }
strcpy(destkey, argv[1]); strcpy(destkey, argv[1]);
@@ -50,7 +50,9 @@ int main (int argc, char *argv[]) {
ok: ok:
printf("creating session...\n"); printf("creating session...\n");
// create TRANSIENT session // create TRANSIENT session
if (sam3CreateSession(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, SAM3_DESTINATION_TRANSIENT, SAM3_SESSION_STREAM, NULL) < 0) { if (sam3CreateSession(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT,
SAM3_DESTINATION_TRANSIENT, SAM3_SESSION_STREAM, 4,
NULL) < 0) {
fprintf(stderr, "FATAL: can't create session\n"); fprintf(stderr, "FATAL: can't create session\n");
return 1; return 1;
} }
@@ -64,12 +66,15 @@ ok:
// //
// now waiting for incoming connection // now waiting for incoming connection
printf("sending test command...\n"); printf("sending test command...\n");
if (sam3tcpPrintf(conn->fd, "test\n") < 0) goto error; if (sam3tcpPrintf(conn->fd, "test\n") < 0)
if (sam3tcpReceiveStr(conn->fd, cmd, sizeof(cmd)) < 0) goto error; goto error;
if (sam3tcpReceiveStr(conn->fd, cmd, sizeof(cmd)) < 0)
goto error;
printf("echo: %s\n", cmd); printf("echo: %s\n", cmd);
// //
printf("sending quit command...\n"); printf("sending quit command...\n");
if (sam3tcpPrintf(conn->fd, "quit\n") < 0) goto error; if (sam3tcpPrintf(conn->fd, "quit\n") < 0)
goto error;
// //
sam3CloseConnection(conn); sam3CloseConnection(conn);
sam3CloseSession(&ses); sam3CloseSession(&ses);

View File

@@ -4,7 +4,8 @@
* To Public License, Version 2, as published by Sam Hocevar. See * To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details. * http://sam.zoy.org/wtfpl/COPYING for more details.
* *
* I2P-Bote: 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV * I2P-Bote:
* 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV
* we are the Borg. */ * we are the Borg. */
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
@@ -14,20 +15,20 @@
#include "../libsam3/libsam3.h" #include "../libsam3/libsam3.h"
#define KEYFILE "streams.key" #define KEYFILE "streams.key"
int main(int argc, char *argv[]) {
int main (int argc, char *argv[]) {
Sam3Session ses; Sam3Session ses;
Sam3Connection *conn; Sam3Connection *conn;
FILE *fl; FILE *fl;
// //
//libsam3_debug = 1; libsam3_debug = 1;
// //
printf("creating session...\n"); printf("creating session...\n");
// create TRANSIENT session // create TRANSIENT session
if (sam3CreateSession(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, SAM3_DESTINATION_TRANSIENT, SAM3_SESSION_STREAM, NULL) < 0) { if (sam3CreateSession(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT,
SAM3_DESTINATION_TRANSIENT, SAM3_SESSION_STREAM, 4,
NULL) < 0) {
fprintf(stderr, "FATAL: can't create session\n"); fprintf(stderr, "FATAL: can't create session\n");
return 1; return 1;
} }
@@ -50,11 +51,14 @@ int main (int argc, char *argv[]) {
for (;;) { for (;;) {
char cmd[256]; char cmd[256];
// //
if (sam3tcpReceiveStr(conn->fd, cmd, sizeof(cmd)) < 0) goto error; if (sam3tcpReceiveStr(conn->fd, cmd, sizeof(cmd)) < 0)
goto error;
printf("cmd: [%s]\n", cmd); printf("cmd: [%s]\n", cmd);
if (strcmp(cmd, "quit") == 0) break; if (strcmp(cmd, "quit") == 0)
break;
// echo command // echo command
if (sam3tcpPrintf(conn->fd, "re: %s\n", cmd) < 0) goto error; if (sam3tcpPrintf(conn->fd, "re: %s\n", cmd) < 0)
goto error;
} }
// //
sam3CloseSession(&ses); sam3CloseSession(&ses);

View File

@@ -4,7 +4,8 @@
* To Public License, Version 2, as published by Sam Hocevar. See * To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details. * http://sam.zoy.org/wtfpl/COPYING for more details.
* *
* I2P-Bote: 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV * I2P-Bote:
* 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV
* we are the Borg. */ * we are the Borg. */
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
@@ -18,21 +19,22 @@
#include "../libsam3a/libsam3a.h" #include "../libsam3a/libsam3a.h"
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static void scbErrorClose (Sam3ASession *ses) { static void scbErrorClose(Sam3ASession *ses) {
fprintf(stderr, "\n===============================\nSESION_ERROR: [%s]\n===============================\n", ses->error); fprintf(stderr,
"\n===============================\nSESION_ERROR: "
"[%s]\n===============================\n",
ses->error);
sam3aCloseSession(ses); // it's safe here sam3aCloseSession(ses); // it's safe here
} }
static void scbNRCreated(Sam3ASession *ses) {
static void scbNRCreated (Sam3ASession *ses) { fprintf(stderr, "\n===============================\nNAME RESOLVED: [%s]\n",
fprintf(stderr, "\n===============================\nNAME RESOLVED: [%s]\n", ses->params); ses->params);
fprintf(stderr, "PUB: %s\n===============================\n", ses->destkey); fprintf(stderr, "PUB: %s\n===============================\n", ses->destkey);
sam3aCloseSession(ses); // it's safe here sam3aCloseSession(ses); // it's safe here
} }
static const Sam3ASessionCallbacks scbNR = { static const Sam3ASessionCallbacks scbNR = {
.cbError = scbErrorClose, .cbError = scbErrorClose,
.cbCreated = scbNRCreated, .cbCreated = scbNRCreated,
@@ -41,16 +43,14 @@ static const Sam3ASessionCallbacks scbNR = {
.cbDestroy = NULL, .cbDestroy = NULL,
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static void scbKGCreated (Sam3ASession *ses) { static void scbKGCreated(Sam3ASession *ses) {
fprintf(stderr, "\n===============================\nKEYS GENERATED\n"); fprintf(stderr, "\n===============================\nKEYS GENERATED\n");
fprintf(stderr, "\rPRIV: %s\n", ses->privkey); fprintf(stderr, "\rPRIV: %s\n", ses->privkey);
fprintf(stderr, "\nPUB: %s\n===============================\n", ses->pubkey); fprintf(stderr, "\nPUB: %s\n===============================\n", ses->pubkey);
sam3aCloseSession(ses); // it's safe here sam3aCloseSession(ses); // it's safe here
} }
static const Sam3ASessionCallbacks scbKG = { static const Sam3ASessionCallbacks scbKG = {
.cbError = scbErrorClose, .cbError = scbErrorClose,
.cbCreated = scbKGCreated, .cbCreated = scbKGCreated,
@@ -59,33 +59,34 @@ static const Sam3ASessionCallbacks scbKG = {
.cbDestroy = NULL, .cbDestroy = NULL,
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static void scbError (Sam3ASession *ses) { static void scbError(Sam3ASession *ses) {
fprintf(stderr, "\n===============================\nSESION_ERROR: [%s]\n===============================\n", ses->error); fprintf(stderr,
"\n===============================\nSESION_ERROR: "
"[%s]\n===============================\n",
ses->error);
} }
static void scbCreated(Sam3ASession *ses) {
static void scbCreated (Sam3ASession *ses) {
fprintf(stderr, "\n===============================\nSESION_CREATED\n"); fprintf(stderr, "\n===============================\nSESION_CREATED\n");
fprintf(stderr, "\rPRIV: %s\n", ses->privkey); fprintf(stderr, "\rPRIV: %s\n", ses->privkey);
fprintf(stderr, "\nPUB: %s\n===============================\n", ses->pubkey); fprintf(stderr, "\nPUB: %s\n===============================\n", ses->pubkey);
sam3aCancelSession(ses); // it's safe here sam3aCancelSession(ses); // it's safe here
} }
static void scbDisconnected(Sam3ASession *ses) {
static void scbDisconnected (Sam3ASession *ses) { fprintf(stderr, "\n===============================\nSESION_DISCONNECTED\n===="
fprintf(stderr, "\n===============================\nSESION_DISCONNECTED\n===============================\n"); "===========================\n");
} }
static void scbDGramRead(Sam3ASession *ses, const void *buf, int bufsize) {
static void scbDGramRead (Sam3ASession *ses, const void *buf, int bufsize) { fprintf(stderr, "\n===============================\nSESION_DATAGRAM_READ\n==="
fprintf(stderr, "\n===============================\nSESION_DATAGRAM_READ\n===============================\n"); "============================\n");
} }
static void scbDestroy(Sam3ASession *ses) {
static void scbDestroy (Sam3ASession *ses) { fprintf(stderr, "\n===============================\nSESION_DESTROYED\n======="
fprintf(stderr, "\n===============================\nSESION_DESTROYED\n===============================\n"); "========================\n");
} }
/** callbacks for our SAM session */ /** callbacks for our SAM session */
@@ -97,18 +98,18 @@ static const Sam3ASessionCallbacks scb = {
.cbDestroy = scbDestroy, .cbDestroy = scbDestroy,
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#define HOST SAM3A_HOST_DEFAULT #define HOST SAM3A_HOST_DEFAULT
//#define HOST "google.com" //#define HOST "google.com"
int main(int argc, char *argv[]) {
int main (int argc, char *argv[]) {
Sam3ASession ses, snr, skg; Sam3ASession ses, snr, skg;
// //
//libsam3a_debug = 1; // libsam3a_debug = 1;
// //
if (sam3aCreateSession(&ses, &scb, HOST, SAM3A_PORT_DEFAULT, SAM3A_DESTINATION_TRANSIENT, SAM3A_SESSION_STREAM) < 0) { if (sam3aCreateSession(&ses, &scb, HOST, SAM3A_PORT_DEFAULT,
SAM3A_DESTINATION_TRANSIENT,
SAM3A_SESSION_STREAM) < 0) {
fprintf(stderr, "FATAL: can't create main session!\n"); fprintf(stderr, "FATAL: can't create main session!\n");
return 1; return 1;
} }
@@ -126,7 +127,8 @@ int main (int argc, char *argv[]) {
return 1; return 1;
} }
// while we have sessions ... // while we have sessions ...
while (sam3aIsActiveSession(&ses) || sam3aIsActiveSession(&snr) || sam3aIsActiveSession(&skg)) { while (sam3aIsActiveSession(&ses) || sam3aIsActiveSession(&snr) ||
sam3aIsActiveSession(&skg)) {
fd_set rds, wrs; fd_set rds, wrs;
int res, maxfd = 0; int res, maxfd = 0;
struct timeval to; struct timeval to;
@@ -134,26 +136,37 @@ int main (int argc, char *argv[]) {
FD_ZERO(&rds); FD_ZERO(&rds);
FD_ZERO(&wrs); FD_ZERO(&wrs);
// obtain the maximum fd for select() // obtain the maximum fd for select()
if (sam3aIsActiveSession(&ses) && (maxfd = sam3aAddSessionToFDS(&ses, -1, &rds, &wrs)) < 0) break; if (sam3aIsActiveSession(&ses) &&
if (sam3aIsActiveSession(&snr) && (maxfd = sam3aAddSessionToFDS(&snr, -1, &rds, &wrs)) < 0) break; (maxfd = sam3aAddSessionToFDS(&ses, -1, &rds, &wrs)) < 0)
if (sam3aIsActiveSession(&skg) && (maxfd = sam3aAddSessionToFDS(&skg, -1, &rds, &wrs)) < 0) break; break;
if (sam3aIsActiveSession(&snr) &&
(maxfd = sam3aAddSessionToFDS(&snr, -1, &rds, &wrs)) < 0)
break;
if (sam3aIsActiveSession(&skg) &&
(maxfd = sam3aAddSessionToFDS(&skg, -1, &rds, &wrs)) < 0)
break;
// set timeout to 1 second // set timeout to 1 second
sam3ams2timeval(&to, 1000); sam3ams2timeval(&to, 1000);
// call select() // call select()
res = select(maxfd+1, &rds, &wrs, NULL, &to); res = select(maxfd + 1, &rds, &wrs, NULL, &to);
if (res < 0) { if (res < 0) {
if (errno == EINTR) continue; if (errno == EINTR)
continue;
fprintf(stderr, "FATAL: select() error!\n"); fprintf(stderr, "FATAL: select() error!\n");
break; break;
} }
if (res == 0) { if (res == 0) {
// idle, no activity // idle, no activity
fprintf(stdout, "."); fflush(stdout); fprintf(stdout, ".");
fflush(stdout);
} else { } else {
// we have activity, process io // we have activity, process io
if (sam3aIsActiveSession(&ses)) sam3aProcessSessionIO(&ses, &rds, &wrs); if (sam3aIsActiveSession(&ses))
if (sam3aIsActiveSession(&snr)) sam3aProcessSessionIO(&snr, &rds, &wrs); sam3aProcessSessionIO(&ses, &rds, &wrs);
if (sam3aIsActiveSession(&skg)) sam3aProcessSessionIO(&skg, &rds, &wrs); if (sam3aIsActiveSession(&snr))
sam3aProcessSessionIO(&snr, &rds, &wrs);
if (sam3aIsActiveSession(&skg))
sam3aProcessSessionIO(&skg, &rds, &wrs);
} }
} }
// close seessions // close seessions

View File

@@ -4,7 +4,8 @@
* To Public License, Version 2, as published by Sam Hocevar. See * To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details. * http://sam.zoy.org/wtfpl/COPYING for more details.
* *
* I2P-Bote: 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV * I2P-Bote:
* 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV
* we are the Borg. */ * we are the Borg. */
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
@@ -18,37 +19,38 @@
#include "../libsam3a/libsam3a.h" #include "../libsam3a/libsam3a.h"
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#define KEYFILE "streams.key" #define KEYFILE "streams.key"
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static void ccbError (Sam3AConnection *ct) { static void ccbError(Sam3AConnection *ct) {
fprintf(stderr, "\n===============================\nCONNECTION_ERROR: [%s]\n===============================\n", ct->error); fprintf(stderr,
"\n===============================\nCONNECTION_ERROR: "
"[%s]\n===============================\n",
ct->error);
} }
static void ccbDisconnected(Sam3AConnection *ct) {
static void ccbDisconnected (Sam3AConnection *ct) { fprintf(stderr, "\n===============================\nCONNECTION_"
fprintf(stderr, "\n===============================\nCONNECTION_DISCONNECTED\n===============================\n"); "DISCONNECTED\n===============================\n");
} }
static void ccbConnected(Sam3AConnection *ct) {
static void ccbConnected (Sam3AConnection *ct) { fprintf(stderr, "\n===============================\nCONNECTION_CONNECTED\n==="
fprintf(stderr, "\n===============================\nCONNECTION_CONNECTED\n===============================\n"); "============================\n");
//sam3aCancelConnection(ct); // cbSent() will not be called // sam3aCancelConnection(ct); // cbSent() will not be called
} }
static void ccbAccepted(Sam3AConnection *ct) {
static void ccbAccepted (Sam3AConnection *ct) { fprintf(stderr, "\n===============================\nCONNECTION_ACCEPTED\n===="
fprintf(stderr, "\n===============================\nCONNECTION_ACCEPTED\n===============================\n"); "===========================\n");
} }
static void ccbSent(Sam3AConnection *ct) {
static void ccbSent (Sam3AConnection *ct) { fprintf(stderr, "\n===============================\nCONNECTION_WANTBYTES\n==="
fprintf(stderr, "\n===============================\nCONNECTION_WANTBYTES\n===============================\n"); "============================\n");
//sam3aCancelConnection(ct); // sam3aCancelConnection(ct);
//sam3aCancelSession(ct->ses); // hehe // sam3aCancelSession(ct->ses); // hehe
fprintf(stderr, "(%p)\n", ct->udata); fprintf(stderr, "(%p)\n", ct->udata);
// //
switch ((intptr_t)ct->udata) { switch ((intptr_t)ct->udata) {
@@ -64,22 +66,24 @@ static void ccbSent (Sam3AConnection *ct) {
sam3aCancelSession(ct->ses); // hehe sam3aCancelSession(ct->ses); // hehe
} }
break; break;
default: return; default:
return;
} }
ct->udata = (void *)(((intptr_t)ct->udata)+1); ct->udata = (void *)(((intptr_t)ct->udata) + 1);
} }
static void ccbRead(Sam3AConnection *ct, const void *buf, int bufsize) {
static void ccbRead (Sam3AConnection *ct, const void *buf, int bufsize) { fprintf(stderr,
fprintf(stderr, "\n===============================\nCONNECTION_GOTBYTES (%d)\n===============================\n", bufsize); "\n===============================\nCONNECTION_GOTBYTES "
"(%d)\n===============================\n",
bufsize);
} }
static void ccbDestroy(Sam3AConnection *ct) {
static void ccbDestroy (Sam3AConnection *ct) { fprintf(stderr, "\n===============================\nCONNECTION_DESTROY\n====="
fprintf(stderr, "\n===============================\nCONNECTION_DESTROY\n===============================\n"); "==========================\n");
} }
static const Sam3AConnectionCallbacks ccb = { static const Sam3AConnectionCallbacks ccb = {
.cbError = ccbError, .cbError = ccbError,
.cbDisconnected = ccbDisconnected, .cbDisconnected = ccbDisconnected,
@@ -90,14 +94,15 @@ static const Sam3AConnectionCallbacks ccb = {
.cbDestroy = ccbDestroy, .cbDestroy = ccbDestroy,
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static void scbError (Sam3ASession *ses) { static void scbError(Sam3ASession *ses) {
fprintf(stderr, "\n===============================\nSESION_ERROR: [%s]\n===============================\n", ses->error); fprintf(stderr,
"\n===============================\nSESION_ERROR: "
"[%s]\n===============================\n",
ses->error);
} }
static void scbCreated(Sam3ASession *ses) {
static void scbCreated (Sam3ASession *ses) {
char destkey[517]; char destkey[517];
FILE *fl; FILE *fl;
// //
@@ -128,22 +133,21 @@ static void scbCreated (Sam3ASession *ses) {
fprintf(stderr, "GOON: creating connection...\n"); fprintf(stderr, "GOON: creating connection...\n");
} }
static void scbDisconnected(Sam3ASession *ses) {
static void scbDisconnected (Sam3ASession *ses) { fprintf(stderr, "\n===============================\nSESION_DISCONNECTED\n===="
fprintf(stderr, "\n===============================\nSESION_DISCONNECTED\n===============================\n"); "===========================\n");
} }
static void scbDGramRead(Sam3ASession *ses, const void *buf, int bufsize) {
static void scbDGramRead (Sam3ASession *ses, const void *buf, int bufsize) { fprintf(stderr, "\n===============================\nSESION_DATAGRAM_READ\n==="
fprintf(stderr, "\n===============================\nSESION_DATAGRAM_READ\n===============================\n"); "============================\n");
} }
static void scbDestroy(Sam3ASession *ses) {
static void scbDestroy (Sam3ASession *ses) { fprintf(stderr, "\n===============================\nSESION_DESTROYED\n======="
fprintf(stderr, "\n===============================\nSESION_DESTROYED\n===============================\n"); "========================\n");
} }
static const Sam3ASessionCallbacks scb = { static const Sam3ASessionCallbacks scb = {
.cbError = scbError, .cbError = scbError,
.cbCreated = scbCreated, .cbCreated = scbCreated,
@@ -152,18 +156,18 @@ static const Sam3ASessionCallbacks scb = {
.cbDestroy = scbDestroy, .cbDestroy = scbDestroy,
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#define HOST SAM3A_HOST_DEFAULT #define HOST SAM3A_HOST_DEFAULT
//#define HOST "google.com" //#define HOST "google.com"
int main(int argc, char *argv[]) {
int main (int argc, char *argv[]) {
Sam3ASession ses; Sam3ASession ses;
// //
libsam3a_debug = 0; libsam3a_debug = 0;
// //
if (sam3aCreateSession(&ses, &scb, HOST, SAM3A_PORT_DEFAULT, SAM3A_DESTINATION_TRANSIENT, SAM3A_SESSION_STREAM) < 0) { if (sam3aCreateSession(&ses, &scb, HOST, SAM3A_PORT_DEFAULT,
SAM3A_DESTINATION_TRANSIENT,
SAM3A_SESSION_STREAM) < 0) {
fprintf(stderr, "FATAL: can't create main session!\n"); fprintf(stderr, "FATAL: can't create main session!\n");
return 1; return 1;
} }
@@ -175,18 +179,23 @@ int main (int argc, char *argv[]) {
// //
FD_ZERO(&rds); FD_ZERO(&rds);
FD_ZERO(&wrs); FD_ZERO(&wrs);
if (sam3aIsActiveSession(&ses) && (maxfd = sam3aAddSessionToFDS(&ses, -1, &rds, &wrs)) < 0) break; if (sam3aIsActiveSession(&ses) &&
(maxfd = sam3aAddSessionToFDS(&ses, -1, &rds, &wrs)) < 0)
break;
sam3ams2timeval(&to, 1000); sam3ams2timeval(&to, 1000);
res = select(maxfd+1, &rds, &wrs, NULL, &to); res = select(maxfd + 1, &rds, &wrs, NULL, &to);
if (res < 0) { if (res < 0) {
if (errno == EINTR) continue; if (errno == EINTR)
continue;
fprintf(stderr, "FATAL: select() error!\n"); fprintf(stderr, "FATAL: select() error!\n");
break; break;
} }
if (res == 0) { if (res == 0) {
fprintf(stdout, "."); fflush(stdout); fprintf(stdout, ".");
fflush(stdout);
} else { } else {
if (sam3aIsActiveSession(&ses)) sam3aProcessSessionIO(&ses, &rds, &wrs); if (sam3aIsActiveSession(&ses))
sam3aProcessSessionIO(&ses, &rds, &wrs);
} }
} }
// //

View File

@@ -4,7 +4,8 @@
* To Public License, Version 2, as published by Sam Hocevar. See * To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details. * http://sam.zoy.org/wtfpl/COPYING for more details.
* *
* I2P-Bote: 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV * I2P-Bote:
* 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV
* we are the Borg. */ * we are the Borg. */
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
@@ -18,11 +19,9 @@
#include "../libsam3a/libsam3a.h" #include "../libsam3a/libsam3a.h"
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#define KEYFILE "streams.key" #define KEYFILE "streams.key"
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
typedef struct { typedef struct {
char *str; char *str;
@@ -31,63 +30,67 @@ typedef struct {
int doQuit; int doQuit;
} ConnData; } ConnData;
static void cdAppendChar(ConnData *d, char ch) {
static void cdAppendChar (ConnData *d, char ch) { if (d->strused + 1 >= d->strsize) {
if (d->strused+1 >= d->strsize) {
// fuck errors // fuck errors
d->strsize = d->strused+1024; d->strsize = d->strused + 1024;
d->str = realloc(d->str, d->strsize+1); d->str = realloc(d->str, d->strsize + 1);
} }
d->str[d->strused++] = ch; d->str[d->strused++] = ch;
d->str[d->strused] = 0; d->str[d->strused] = 0;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static void ccbError (Sam3AConnection *ct) { static void ccbError(Sam3AConnection *ct) {
fprintf(stderr, "\n===============================\nCONNECTION_ERROR: [%s]\n===============================\n", ct->error); fprintf(stderr,
"\n===============================\nCONNECTION_ERROR: "
"[%s]\n===============================\n",
ct->error);
} }
static void ccbDisconnected(Sam3AConnection *ct) {
static void ccbDisconnected (Sam3AConnection *ct) { fprintf(stderr, "\n===============================\nCONNECTION_"
fprintf(stderr, "\n===============================\nCONNECTION_DISCONNECTED\n===============================\n"); "DISCONNECTED\n===============================\n");
} }
static void ccbConnected(Sam3AConnection *ct) {
static void ccbConnected (Sam3AConnection *ct) { fprintf(stderr, "\n===============================\nCONNECTION_CONNECTED\n==="
fprintf(stderr, "\n===============================\nCONNECTION_CONNECTED\n===============================\n"); "============================\n");
//sam3aCancelConnection(ct); // cbSent() will not be called // sam3aCancelConnection(ct); // cbSent() will not be called
} }
static void ccbAccepted(Sam3AConnection *ct) {
static void ccbAccepted (Sam3AConnection *ct) { fprintf(stderr, "\n===============================\nCONNECTION_ACCEPTED\n===="
fprintf(stderr, "\n===============================\nCONNECTION_ACCEPTED\n===============================\n"); "===========================\n");
fprintf(stderr, "FROM: %s\n===============================\n", ct->destkey); fprintf(stderr, "FROM: %s\n===============================\n", ct->destkey);
} }
static void ccbSent(Sam3AConnection *ct) {
static void ccbSent (Sam3AConnection *ct) {
ConnData *d = (ConnData *)ct->udata; ConnData *d = (ConnData *)ct->udata;
// //
fprintf(stderr, "\n===============================\nCONNECTION_WANTBYTES\n===============================\n"); fprintf(stderr, "\n===============================\nCONNECTION_WANTBYTES\n==="
"============================\n");
if (d->doQuit) { if (d->doQuit) {
sam3aCancelSession(ct->ses); // hehe sam3aCancelSession(ct->ses); // hehe
} }
} }
static void ccbRead(Sam3AConnection *ct, const void *buf, int bufsize) {
static void ccbRead (Sam3AConnection *ct, const void *buf, int bufsize) {
const char *b = (const char *)buf; const char *b = (const char *)buf;
ConnData *d = (ConnData *)ct->udata; ConnData *d = (ConnData *)ct->udata;
// //
fprintf(stderr, "\n===============================\nCONNECTION_GOTBYTES (%d)\n===============================\n", bufsize); fprintf(stderr,
"\n===============================\nCONNECTION_GOTBYTES "
"(%d)\n===============================\n",
bufsize);
while (bufsize > 0) { while (bufsize > 0) {
cdAppendChar(ct->udata, *b); cdAppendChar(ct->udata, *b);
if (*b == '\n') { if (*b == '\n') {
fprintf(stderr, "cmd: %s", d->str); fprintf(stderr, "cmd: %s", d->str);
if (strcasecmp(d->str, "quit\n") == 0) d->doQuit = 1; if (strcasecmp(d->str, "quit\n") == 0)
d->doQuit = 1;
if (sam3aSend(ct, d->str, -1) < 0) { if (sam3aSend(ct, d->str, -1) < 0) {
//sam3aCancelConnection(ct); // hehe // sam3aCancelConnection(ct); // hehe
sam3aCancelSession(ct->ses); // hehe sam3aCancelSession(ct->ses); // hehe
return; return;
} }
@@ -99,18 +102,18 @@ static void ccbRead (Sam3AConnection *ct, const void *buf, int bufsize) {
} }
} }
static void ccbDestroy(Sam3AConnection *ct) {
static void ccbDestroy (Sam3AConnection *ct) { fprintf(stderr, "\n===============================\nCONNECTION_DESTROY\n====="
fprintf(stderr, "\n===============================\nCONNECTION_DESTROY\n===============================\n"); "==========================\n");
if (ct->udata != NULL) { if (ct->udata != NULL) {
ConnData *d = (ConnData *)ct->udata; ConnData *d = (ConnData *)ct->udata;
// //
if (d->str != NULL) free(d->str); if (d->str != NULL)
free(d->str);
free(d); free(d);
} }
} }
static const Sam3AConnectionCallbacks ccb = { static const Sam3AConnectionCallbacks ccb = {
.cbError = ccbError, .cbError = ccbError,
.cbDisconnected = ccbDisconnected, .cbDisconnected = ccbDisconnected,
@@ -121,14 +124,15 @@ static const Sam3AConnectionCallbacks ccb = {
.cbDestroy = ccbDestroy, .cbDestroy = ccbDestroy,
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static void scbError (Sam3ASession *ses) { static void scbError(Sam3ASession *ses) {
fprintf(stderr, "\n===============================\nSESION_ERROR: [%s]\n===============================\n", ses->error); fprintf(stderr,
"\n===============================\nSESION_ERROR: "
"[%s]\n===============================\n",
ses->error);
} }
static void scbCreated(Sam3ASession *ses) {
static void scbCreated (Sam3ASession *ses) {
FILE *fl; FILE *fl;
Sam3AConnection *conn; Sam3AConnection *conn;
// //
@@ -160,22 +164,21 @@ static void scbCreated (Sam3ASession *ses) {
fprintf(stderr, "GOON: accepting connection...\n"); fprintf(stderr, "GOON: accepting connection...\n");
} }
static void scbDisconnected(Sam3ASession *ses) {
static void scbDisconnected (Sam3ASession *ses) { fprintf(stderr, "\n===============================\nSESION_DISCONNECTED\n===="
fprintf(stderr, "\n===============================\nSESION_DISCONNECTED\n===============================\n"); "===========================\n");
} }
static void scbDGramRead(Sam3ASession *ses, const void *buf, int bufsize) {
static void scbDGramRead (Sam3ASession *ses, const void *buf, int bufsize) { fprintf(stderr, "\n===============================\nSESION_DATAGRAM_READ\n==="
fprintf(stderr, "\n===============================\nSESION_DATAGRAM_READ\n===============================\n"); "============================\n");
} }
static void scbDestroy(Sam3ASession *ses) {
static void scbDestroy (Sam3ASession *ses) { fprintf(stderr, "\n===============================\nSESION_DESTROYED\n======="
fprintf(stderr, "\n===============================\nSESION_DESTROYED\n===============================\n"); "========================\n");
} }
static const Sam3ASessionCallbacks scb = { static const Sam3ASessionCallbacks scb = {
.cbError = scbError, .cbError = scbError,
.cbCreated = scbCreated, .cbCreated = scbCreated,
@@ -184,18 +187,18 @@ static const Sam3ASessionCallbacks scb = {
.cbDestroy = scbDestroy, .cbDestroy = scbDestroy,
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#define HOST SAM3A_HOST_DEFAULT #define HOST SAM3A_HOST_DEFAULT
//#define HOST "google.com" //#define HOST "google.com"
int main(int argc, char *argv[]) {
int main (int argc, char *argv[]) {
Sam3ASession ses; Sam3ASession ses;
// //
libsam3a_debug = 0; libsam3a_debug = 0;
// //
if (sam3aCreateSession(&ses, &scb, HOST, SAM3A_PORT_DEFAULT, SAM3A_DESTINATION_TRANSIENT, SAM3A_SESSION_STREAM) < 0) { if (sam3aCreateSession(&ses, &scb, HOST, SAM3A_PORT_DEFAULT,
SAM3A_DESTINATION_TRANSIENT,
SAM3A_SESSION_STREAM) < 0) {
fprintf(stderr, "FATAL: can't create main session!\n"); fprintf(stderr, "FATAL: can't create main session!\n");
return 1; return 1;
} }
@@ -207,18 +210,23 @@ int main (int argc, char *argv[]) {
// //
FD_ZERO(&rds); FD_ZERO(&rds);
FD_ZERO(&wrs); FD_ZERO(&wrs);
if (sam3aIsActiveSession(&ses) && (maxfd = sam3aAddSessionToFDS(&ses, -1, &rds, &wrs)) < 0) break; if (sam3aIsActiveSession(&ses) &&
(maxfd = sam3aAddSessionToFDS(&ses, -1, &rds, &wrs)) < 0)
break;
sam3ams2timeval(&to, 1000); sam3ams2timeval(&to, 1000);
res = select(maxfd+1, &rds, &wrs, NULL, &to); res = select(maxfd + 1, &rds, &wrs, NULL, &to);
if (res < 0) { if (res < 0) {
if (errno == EINTR) continue; if (errno == EINTR)
continue;
fprintf(stderr, "FATAL: select() error!\n"); fprintf(stderr, "FATAL: select() error!\n");
break; break;
} }
if (res == 0) { if (res == 0) {
fprintf(stdout, "."); fflush(stdout); fprintf(stdout, ".");
fflush(stdout);
} else { } else {
if (sam3aIsActiveSession(&ses)) sam3aProcessSessionIO(&ses, &rds, &wrs); if (sam3aIsActiveSession(&ses))
sam3aProcessSessionIO(&ses, &rds, &wrs);
} }
} }
// //

View File

@@ -26,10 +26,10 @@
#include "tinytest_local.h" #include "tinytest_local.h"
#endif #endif
#include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <assert.h>
#ifndef NO_FORKING #ifndef NO_FORKING
@@ -71,9 +71,9 @@ static int opt_nofork = 0; /**< Suppress calls to fork() for debugging. */
static int opt_verbosity = 1; /**< -==quiet,0==terse,1==normal,2==verbose */ static int opt_verbosity = 1; /**< -==quiet,0==terse,1==normal,2==verbose */
const char *verbosity_flag = ""; const char *verbosity_flag = "";
const struct testlist_alias_t *cfg_aliases=NULL; const struct testlist_alias_t *cfg_aliases = NULL;
enum outcome { SKIP=2, OK=1, FAIL=0 }; enum outcome { SKIP = 2, OK = 1, FAIL = 0 };
static enum outcome cur_test_outcome = FAIL; static enum outcome cur_test_outcome = FAIL;
const char *cur_test_prefix = NULL; /**< prefix of the current test group */ const char *cur_test_prefix = NULL; /**< prefix of the current test group */
/** Name of the current test, if we haven't logged is yet. Used for --quiet */ /** Name of the current test, if we haven't logged is yet. Used for --quiet */
@@ -81,23 +81,21 @@ const char *cur_test_name = NULL;
#ifdef _WIN32 #ifdef _WIN32
/* Copy of argv[0] for win32. */ /* Copy of argv[0] for win32. */
static char commandname[MAX_PATH+1]; static char commandname[MAX_PATH + 1];
#endif #endif
static void usage(struct testgroup_t *groups, int list_groups) static void usage(struct testgroup_t *groups, int list_groups)
__attribute__((noreturn)); __attribute__((noreturn));
static int process_test_option(struct testgroup_t *groups, const char *test); static int process_test_option(struct testgroup_t *groups, const char *test);
static enum outcome static enum outcome testcase_run_bare_(const struct testcase_t *testcase) {
testcase_run_bare_(const struct testcase_t *testcase)
{
void *env = NULL; void *env = NULL;
enum outcome outcome; enum outcome outcome;
if (testcase->setup) { if (testcase->setup) {
env = testcase->setup->setup_fn(testcase); env = testcase->setup->setup_fn(testcase);
if (!env) if (!env)
return FAIL; return FAIL;
else if (env == (void*)TT_SKIP) else if (env == (void *)TT_SKIP)
return SKIP; return SKIP;
} }
@@ -117,10 +115,8 @@ testcase_run_bare_(const struct testcase_t *testcase)
#ifndef NO_FORKING #ifndef NO_FORKING
static enum outcome static enum outcome testcase_run_forked_(const struct testgroup_t *group,
testcase_run_forked_(const struct testgroup_t *group, const struct testcase_t *testcase) {
const struct testcase_t *testcase)
{
#ifdef _WIN32 #ifdef _WIN32
/* Fork? On Win32? How primitive! We'll do what the smart kids do: /* Fork? On Win32? How primitive! We'll do what the smart kids do:
we'll invoke our own exe (whose name we recall from the command we'll invoke our own exe (whose name we recall from the command
@@ -131,7 +127,7 @@ testcase_run_forked_(const struct testgroup_t *group,
share no state between tests.) share no state between tests.)
*/ */
int ok; int ok;
char buffer[LONGEST_TEST_NAME+256]; char buffer[LONGEST_TEST_NAME + 256];
STARTUPINFOA si; STARTUPINFOA si;
PROCESS_INFORMATION info; PROCESS_INFORMATION info;
DWORD exitcode; DWORD exitcode;
@@ -141,18 +137,18 @@ testcase_run_forked_(const struct testgroup_t *group,
" called from within tinytest_main.\n"); " called from within tinytest_main.\n");
abort(); abort();
} }
if (opt_verbosity>0) if (opt_verbosity > 0)
printf("[forking] "); printf("[forking] ");
snprintf(buffer, sizeof(buffer), "%s --RUNNING-FORKED %s %s%s", snprintf(buffer, sizeof(buffer), "%s --RUNNING-FORKED %s %s%s", commandname,
commandname, verbosity_flag, group->prefix, testcase->name); verbosity_flag, group->prefix, testcase->name);
memset(&si, 0, sizeof(si)); memset(&si, 0, sizeof(si));
memset(&info, 0, sizeof(info)); memset(&info, 0, sizeof(info));
si.cb = sizeof(si); si.cb = sizeof(si);
ok = CreateProcessA(commandname, buffer, NULL, NULL, 0, ok = CreateProcessA(commandname, buffer, NULL, NULL, 0, 0, NULL, NULL, &si,
0, NULL, NULL, &si, &info); &info);
if (!ok) { if (!ok) {
printf("CreateProcess failed!\n"); printf("CreateProcess failed!\n");
return 0; return 0;
@@ -175,7 +171,7 @@ testcase_run_forked_(const struct testgroup_t *group,
if (pipe(outcome_pipe)) if (pipe(outcome_pipe))
perror("opening pipe"); perror("opening pipe");
if (opt_verbosity>0) if (opt_verbosity > 0)
printf("[forking] "); printf("[forking] ");
pid = fork(); pid = fork();
#ifdef FORK_BREAKS_GCOV #ifdef FORK_BREAKS_GCOV
@@ -187,7 +183,7 @@ testcase_run_forked_(const struct testgroup_t *group,
char b[1]; char b[1];
close(outcome_pipe[0]); close(outcome_pipe[0]);
test_r = testcase_run_bare_(testcase); test_r = testcase_run_bare_(testcase);
assert(0<=(int)test_r && (int)test_r<=2); assert(0 <= (int)test_r && (int)test_r <= 2);
b[0] = "NYS"[test_r]; b[0] = "NYS"[test_r];
write_r = (int)write(outcome_pipe[1], b, 1); write_r = (int)write(outcome_pipe[1], b, 1);
if (write_r != 1) { if (write_r != 1) {
@@ -212,38 +208,36 @@ testcase_run_forked_(const struct testgroup_t *group,
} }
waitpid(pid, &status, 0); waitpid(pid, &status, 0);
close(outcome_pipe[0]); close(outcome_pipe[0]);
return b[0]=='Y' ? OK : (b[0]=='S' ? SKIP : FAIL); return b[0] == 'Y' ? OK : (b[0] == 'S' ? SKIP : FAIL);
} }
#endif #endif
} }
#endif /* !NO_FORKING */ #endif /* !NO_FORKING */
int int testcase_run_one(const struct testgroup_t *group,
testcase_run_one(const struct testgroup_t *group, const struct testcase_t *testcase) {
const struct testcase_t *testcase)
{
enum outcome outcome; enum outcome outcome;
if (testcase->flags & (TT_SKIP|TT_OFF_BY_DEFAULT)) { if (testcase->flags & (TT_SKIP | TT_OFF_BY_DEFAULT)) {
if (opt_verbosity>0) if (opt_verbosity > 0)
printf("%s%s: %s\n", printf("%s%s: %s\n", group->prefix, testcase->name,
group->prefix, testcase->name,
(testcase->flags & TT_SKIP) ? "SKIPPED" : "DISABLED"); (testcase->flags & TT_SKIP) ? "SKIPPED" : "DISABLED");
++n_skipped; ++n_skipped;
return SKIP; return SKIP;
} }
if (opt_verbosity>0 && !opt_forked) { if (opt_verbosity > 0 && !opt_forked) {
printf("%s%s: ", group->prefix, testcase->name); printf("%s%s: ", group->prefix, testcase->name);
} else { } else {
if (opt_verbosity==0) printf("."); if (opt_verbosity == 0)
printf(".");
cur_test_prefix = group->prefix; cur_test_prefix = group->prefix;
cur_test_name = testcase->name; cur_test_name = testcase->name;
} }
#ifndef NO_FORKING #ifndef NO_FORKING
if ((testcase->flags & TT_FORK) && !(opt_forked||opt_nofork)) { if ((testcase->flags & TT_FORK) && !(opt_forked || opt_nofork)) {
outcome = testcase_run_forked_(group, testcase); outcome = testcase_run_forked_(group, testcase);
} else { } else {
#else #else
@@ -254,11 +248,11 @@ testcase_run_one(const struct testgroup_t *group,
if (outcome == OK) { if (outcome == OK) {
++n_ok; ++n_ok;
if (opt_verbosity>0 && !opt_forked) if (opt_verbosity > 0 && !opt_forked)
puts(opt_verbosity==1?"OK":""); puts(opt_verbosity == 1 ? "OK" : "");
} else if (outcome == SKIP) { } else if (outcome == SKIP) {
++n_skipped; ++n_skipped;
if (opt_verbosity>0 && !opt_forked) if (opt_verbosity > 0 && !opt_forked)
puts("SKIPPED"); puts("SKIPPED");
} else { } else {
++n_bad; ++n_bad;
@@ -267,27 +261,26 @@ testcase_run_one(const struct testgroup_t *group,
} }
if (opt_forked) { if (opt_forked) {
exit(outcome==OK ? 0 : (outcome==SKIP?MAGIC_EXITCODE : 1)); exit(outcome == OK ? 0 : (outcome == SKIP ? MAGIC_EXITCODE : 1));
return 1; /* unreachable */ return 1; /* unreachable */
} else { } else {
return (int)outcome; return (int)outcome;
} }
} }
int int tinytest_set_flag_(struct testgroup_t *groups, const char *arg, int set,
tinytest_set_flag_(struct testgroup_t *groups, const char *arg, int set, unsigned long flag) unsigned long flag) {
{
int i, j; int i, j;
size_t length = LONGEST_TEST_NAME; size_t length = LONGEST_TEST_NAME;
char fullname[LONGEST_TEST_NAME]; char fullname[LONGEST_TEST_NAME];
int found=0; int found = 0;
if (strstr(arg, "..")) if (strstr(arg, ".."))
length = strstr(arg,"..")-arg; length = strstr(arg, "..") - arg;
for (i=0; groups[i].prefix; ++i) { for (i = 0; groups[i].prefix; ++i) {
for (j=0; groups[i].cases[j].name; ++j) { for (j = 0; groups[i].cases[j].name; ++j) {
struct testcase_t *testcase = &groups[i].cases[j]; struct testcase_t *testcase = &groups[i].cases[j];
snprintf(fullname, sizeof(fullname), "%s%s", snprintf(fullname, sizeof(fullname), "%s%s", groups[i].prefix,
groups[i].prefix, testcase->name); testcase->name);
if (!flag) { /* Hack! */ if (!flag) { /* Hack! */
printf(" %s", fullname); printf(" %s", fullname);
if (testcase->flags & TT_OFF_BY_DEFAULT) if (testcase->flags & TT_OFF_BY_DEFAULT)
@@ -309,9 +302,7 @@ tinytest_set_flag_(struct testgroup_t *groups, const char *arg, int set, unsigne
return found; return found;
} }
static void static void usage(struct testgroup_t *groups, int list_groups) {
usage(struct testgroup_t *groups, int list_groups)
{
puts("Options are: [--verbose|--quiet|--terse] [--no-fork]"); puts("Options are: [--verbose|--quiet|--terse] [--no-fork]");
puts(" Specify tests by name, or using a prefix ending with '..'"); puts(" Specify tests by name, or using a prefix ending with '..'");
puts(" To skip a test, prefix its name with a colon."); puts(" To skip a test, prefix its name with a colon.");
@@ -324,29 +315,25 @@ usage(struct testgroup_t *groups, int list_groups)
exit(0); exit(0);
} }
static int static int process_test_alias(struct testgroup_t *groups, const char *test) {
process_test_alias(struct testgroup_t *groups, const char *test)
{
int i, j, n, r; int i, j, n, r;
for (i=0; cfg_aliases && cfg_aliases[i].name; ++i) { for (i = 0; cfg_aliases && cfg_aliases[i].name; ++i) {
if (!strcmp(cfg_aliases[i].name, test)) { if (!strcmp(cfg_aliases[i].name, test)) {
n = 0; n = 0;
for (j = 0; cfg_aliases[i].tests[j]; ++j) { for (j = 0; cfg_aliases[i].tests[j]; ++j) {
r = process_test_option(groups, cfg_aliases[i].tests[j]); r = process_test_option(groups, cfg_aliases[i].tests[j]);
if (r<0) if (r < 0)
return -1; return -1;
n += r; n += r;
} }
return n; return n;
} }
} }
printf("No such test alias as @%s!",test); printf("No such test alias as @%s!", test);
return -1; return -1;
} }
static int static int process_test_option(struct testgroup_t *groups, const char *test) {
process_test_option(struct testgroup_t *groups, const char *test)
{
int flag = TT_ENABLED_; int flag = TT_ENABLED_;
int n = 0; int n = 0;
if (test[0] == '@') { if (test[0] == '@') {
@@ -371,16 +358,12 @@ process_test_option(struct testgroup_t *groups, const char *test)
return n; return n;
} }
void void tinytest_set_aliases(const struct testlist_alias_t *aliases) {
tinytest_set_aliases(const struct testlist_alias_t *aliases)
{
cfg_aliases = aliases; cfg_aliases = aliases;
} }
int int tinytest_main(int c, const char **v, struct testgroup_t *groups) {
tinytest_main(int c, const char **v, struct testgroup_t *groups) int i, j, n = 0;
{
int i, j, n=0;
#ifdef _WIN32 #ifdef _WIN32
const char *sp = strrchr(v[0], '.'); const char *sp = strrchr(v[0], '.');
@@ -388,9 +371,9 @@ tinytest_main(int c, const char **v, struct testgroup_t *groups)
if (!sp || stricmp(sp, ".exe")) if (!sp || stricmp(sp, ".exe"))
extension = ".exe"; /* Add an exe so CreateProcess will work */ extension = ".exe"; /* Add an exe so CreateProcess will work */
snprintf(commandname, sizeof(commandname), "%s%s", v[0], extension); snprintf(commandname, sizeof(commandname), "%s%s", v[0], extension);
commandname[MAX_PATH]='\0'; commandname[MAX_PATH] = '\0';
#endif #endif
for (i=1; i<c; ++i) { for (i = 1; i < c; ++i) {
if (v[i][0] == '-') { if (v[i][0] == '-') {
if (!strcmp(v[i], "--RUNNING-FORKED")) { if (!strcmp(v[i], "--RUNNING-FORKED")) {
opt_forked = 1; opt_forked = 1;
@@ -410,12 +393,12 @@ tinytest_main(int c, const char **v, struct testgroup_t *groups)
} else if (!strcmp(v[i], "--list-tests")) { } else if (!strcmp(v[i], "--list-tests")) {
usage(groups, 1); usage(groups, 1);
} else { } else {
printf("Unknown option %s. Try --help\n",v[i]); printf("Unknown option %s. Try --help\n", v[i]);
return -1; return -1;
} }
} else { } else {
int r = process_test_option(groups, v[i]); int r = process_test_option(groups, v[i]);
if (r<0) if (r < 0)
return -1; return -1;
n += r; n += r;
} }
@@ -428,63 +411,53 @@ tinytest_main(int c, const char **v, struct testgroup_t *groups)
#endif #endif
++in_tinytest_main; ++in_tinytest_main;
for (i=0; groups[i].prefix; ++i) for (i = 0; groups[i].prefix; ++i)
for (j=0; groups[i].cases[j].name; ++j) for (j = 0; groups[i].cases[j].name; ++j)
if (groups[i].cases[j].flags & TT_ENABLED_) if (groups[i].cases[j].flags & TT_ENABLED_)
testcase_run_one(&groups[i], testcase_run_one(&groups[i], &groups[i].cases[j]);
&groups[i].cases[j]);
--in_tinytest_main; --in_tinytest_main;
if (opt_verbosity==0) if (opt_verbosity == 0)
puts(""); puts("");
if (n_bad) if (n_bad)
printf("%d/%d TESTS FAILED. (%d skipped)\n", n_bad, printf("%d/%d TESTS FAILED. (%d skipped)\n", n_bad, n_bad + n_ok,
n_bad+n_ok,n_skipped); n_skipped);
else if (opt_verbosity >= 1) else if (opt_verbosity >= 1)
printf("%d tests ok. (%d skipped)\n", n_ok, n_skipped); printf("%d tests ok. (%d skipped)\n", n_ok, n_skipped);
return (n_bad == 0) ? 0 : 1; return (n_bad == 0) ? 0 : 1;
} }
int int tinytest_get_verbosity_(void) { return opt_verbosity; }
tinytest_get_verbosity_(void)
{
return opt_verbosity;
}
void void tinytest_set_test_failed_(void) {
tinytest_set_test_failed_(void)
{
if (opt_verbosity <= 0 && cur_test_name) { if (opt_verbosity <= 0 && cur_test_name) {
if (opt_verbosity==0) puts(""); if (opt_verbosity == 0)
puts("");
printf("%s%s: ", cur_test_prefix, cur_test_name); printf("%s%s: ", cur_test_prefix, cur_test_name);
cur_test_name = NULL; cur_test_name = NULL;
} }
cur_test_outcome = FAIL; cur_test_outcome = FAIL;
} }
void void tinytest_set_test_skipped_(void) {
tinytest_set_test_skipped_(void) if (cur_test_outcome == OK)
{
if (cur_test_outcome==OK)
cur_test_outcome = SKIP; cur_test_outcome = SKIP;
} }
char * char *tinytest_format_hex_(const void *val_, unsigned long len) {
tinytest_format_hex_(const void *val_, unsigned long len) const unsigned char *val = (unsigned char *)val_;
{
const unsigned char *val = (unsigned char *) val_;
char *result, *cp; char *result, *cp;
size_t i; size_t i;
if (!val) if (!val)
return strdup("null"); return strdup("null");
if (!(result = (char *) malloc(len*2+1))) if (!(result = (char *)malloc(len * 2 + 1)))
return strdup("<allocation failure>"); return strdup("<allocation failure>");
cp = result; cp = result;
for (i=0;i<len;++i) { for (i = 0; i < len; ++i) {
*cp++ = "0123456789ABCDEF"[val[i] >> 4]; *cp++ = "0123456789ABCDEF"[val[i] >> 4];
*cp++ = "0123456789ABCDEF"[val[i] & 0x0f]; *cp++ = "0123456789ABCDEF"[val[i] & 0x0f];
} }

View File

@@ -27,15 +27,15 @@
#define TINYTEST_H_INCLUDED_ #define TINYTEST_H_INCLUDED_
/** Flag for a test that needs to run in a subprocess. */ /** Flag for a test that needs to run in a subprocess. */
#define TT_FORK (1<<0) #define TT_FORK (1 << 0)
/** Runtime flag for a test we've decided to skip. */ /** Runtime flag for a test we've decided to skip. */
#define TT_SKIP (1<<1) #define TT_SKIP (1 << 1)
/** Internal runtime flag for a test we've decided to run. */ /** Internal runtime flag for a test we've decided to run. */
#define TT_ENABLED_ (1<<2) #define TT_ENABLED_ (1 << 2)
/** Flag for a test that's off by default. */ /** Flag for a test that's off by default. */
#define TT_OFF_BY_DEFAULT (1<<3) #define TT_OFF_BY_DEFAULT (1 << 3)
/** If you add your own flags, make them start at this point. */ /** If you add your own flags, make them start at this point. */
#define TT_FIRST_USER_FLAG (1<<4) #define TT_FIRST_USER_FLAG (1 << 4)
typedef void (*testcase_fn)(void *); typedef void (*testcase_fn)(void *);
@@ -57,20 +57,23 @@ struct testcase_t {
const struct testcase_setup_t *setup; /**< Optional setup/cleanup fns*/ const struct testcase_setup_t *setup; /**< Optional setup/cleanup fns*/
void *setup_data; /**< Extra data usable by setup function */ void *setup_data; /**< Extra data usable by setup function */
}; };
#define END_OF_TESTCASES { NULL, NULL, 0, NULL, NULL } #define END_OF_TESTCASES \
{ NULL, NULL, 0, NULL, NULL }
/** A group of tests that are selectable together. */ /** A group of tests that are selectable together. */
struct testgroup_t { struct testgroup_t {
const char *prefix; /**< Prefix to prepend to testnames. */ const char *prefix; /**< Prefix to prepend to testnames. */
struct testcase_t *cases; /** Array, ending with END_OF_TESTCASES */ struct testcase_t *cases; /** Array, ending with END_OF_TESTCASES */
}; };
#define END_OF_GROUPS { NULL, NULL} #define END_OF_GROUPS \
{ NULL, NULL }
struct testlist_alias_t { struct testlist_alias_t {
const char *name; const char *name;
const char **tests; const char **tests;
}; };
#define END_OF_ALIASES { NULL, NULL } #define END_OF_ALIASES \
{ NULL, NULL }
/** Implementation: called from a test to indicate failure, before logging. */ /** Implementation: called from a test to indicate failure, before logging. */
void tinytest_set_test_failed_(void); void tinytest_set_test_failed_(void);
@@ -80,7 +83,8 @@ void tinytest_set_test_skipped_(void);
int tinytest_get_verbosity_(void); int tinytest_get_verbosity_(void);
/** Implementation: Set a flag on tests matching a name; returns number /** Implementation: Set a flag on tests matching a name; returns number
* of tests that matched. */ * of tests that matched. */
int tinytest_set_flag_(struct testgroup_t *, const char *, int set, unsigned long); int tinytest_set_flag_(struct testgroup_t *, const char *, int set,
unsigned long);
/** Implementation: Put a chunk of memory into hex. */ /** Implementation: Put a chunk of memory into hex. */
char *tinytest_format_hex_(const void *, unsigned long); char *tinytest_format_hex_(const void *, unsigned long);
@@ -89,7 +93,7 @@ char *tinytest_format_hex_(const void *, unsigned long);
tinytest_set_flag_(groups, named, 1, TT_SKIP) tinytest_set_flag_(groups, named, 1, TT_SKIP)
/** Run a single testcase in a single group. */ /** Run a single testcase in a single group. */
int testcase_run_one(const struct testgroup_t *,const struct testcase_t *); int testcase_run_one(const struct testgroup_t *, const struct testcase_t *);
void tinytest_set_aliases(const struct testlist_alias_t *aliases); void tinytest_set_aliases(const struct testlist_alias_t *aliases);

View File

@@ -28,20 +28,24 @@
/* Helpers for defining statement-like macros */ /* Helpers for defining statement-like macros */
#define TT_STMT_BEGIN do { #define TT_STMT_BEGIN do {
#define TT_STMT_END } while (0) #define TT_STMT_END \
} \
while (0)
/* Redefine this if your test functions want to abort with something besides /* Redefine this if your test functions want to abort with something besides
* "goto end;" */ * "goto end;" */
#ifndef TT_EXIT_TEST_FUNCTION #ifndef TT_EXIT_TEST_FUNCTION
#define TT_EXIT_TEST_FUNCTION TT_STMT_BEGIN goto end; TT_STMT_END #define TT_EXIT_TEST_FUNCTION \
TT_STMT_BEGIN goto end; \
TT_STMT_END
#endif #endif
/* Redefine this if you want to note success/failure in some different way. */ /* Redefine this if you want to note success/failure in some different way. */
#ifndef TT_DECLARE #ifndef TT_DECLARE
#define TT_DECLARE(prefix, args) \ #define TT_DECLARE(prefix, args) \
TT_STMT_BEGIN \ TT_STMT_BEGIN \
printf("\n %s %s:%d: ",prefix,__FILE__,__LINE__); \ printf("\n %s %s:%d: ", prefix, __FILE__, __LINE__); \
printf args ; \ printf args; \
TT_STMT_END TT_STMT_END
#endif #endif
@@ -51,7 +55,8 @@
/* Announce a non-failure if we're verbose. */ /* Announce a non-failure if we're verbose. */
#define TT_BLATHER(args) \ #define TT_BLATHER(args) \
TT_STMT_BEGIN \ TT_STMT_BEGIN \
if (tinytest_get_verbosity_()>1) TT_DECLARE(" OK", args); \ if (tinytest_get_verbosity_() > 1) \
TT_DECLARE(" OK", args); \
TT_STMT_END TT_STMT_END
#define TT_DIE(args) \ #define TT_DIE(args) \
@@ -69,13 +74,15 @@
/* Fail and abort the current test for the reason in msg */ /* Fail and abort the current test for the reason in msg */
#define tt_abort_printf(msg) TT_DIE(msg) #define tt_abort_printf(msg) TT_DIE(msg)
#define tt_abort_perror(op) TT_DIE(("%s: %s [%d]",(op),strerror(errno), errno)) #define tt_abort_perror(op) \
TT_DIE(("%s: %s [%d]", (op), strerror(errno), errno))
#define tt_abort_msg(msg) TT_DIE(("%s", msg)) #define tt_abort_msg(msg) TT_DIE(("%s", msg))
#define tt_abort() TT_DIE(("%s", "(Failed.)")) #define tt_abort() TT_DIE(("%s", "(Failed.)"))
/* Fail but do not abort the current test for the reason in msg. */ /* Fail but do not abort the current test for the reason in msg. */
#define tt_fail_printf(msg) TT_FAIL(msg) #define tt_fail_printf(msg) TT_FAIL(msg)
#define tt_fail_perror(op) TT_FAIL(("%s: %s [%d]",(op),strerror(errno), errno)) #define tt_fail_perror(op) \
TT_FAIL(("%s: %s [%d]", (op), strerror(errno), errno))
#define tt_fail_msg(msg) TT_FAIL(("%s", msg)) #define tt_fail_msg(msg) TT_FAIL(("%s", msg))
#define tt_fail() TT_FAIL(("%s", "(Failed.)")) #define tt_fail() TT_FAIL(("%s", "(Failed.)"))
@@ -90,33 +97,32 @@
TT_STMT_BEGIN \ TT_STMT_BEGIN \
if (!(b)) { \ if (!(b)) { \
tinytest_set_test_failed_(); \ tinytest_set_test_failed_(); \
TT_GRIPE(("%s",msg)); \ TT_GRIPE(("%s", msg)); \
fail; \ fail; \
} else { \ } else { \
TT_BLATHER(("%s",msg)); \ TT_BLATHER(("%s", msg)); \
} \ } \
TT_STMT_END TT_STMT_END
/* Assert b, but do not stop the test if b fails. Log msg on failure. */ /* Assert b, but do not stop the test if b fails. Log msg on failure. */
#define tt_want_msg(b, msg) \ #define tt_want_msg(b, msg) tt_want_(b, msg, );
tt_want_(b, msg, );
/* Assert b and stop the test if b fails. Log msg on failure. */ /* Assert b and stop the test if b fails. Log msg on failure. */
#define tt_assert_msg(b, msg) \ #define tt_assert_msg(b, msg) tt_want_(b, msg, TT_EXIT_TEST_FUNCTION);
tt_want_(b, msg, TT_EXIT_TEST_FUNCTION);
/* Assert b, but do not stop the test if b fails. */ /* Assert b, but do not stop the test if b fails. */
#define tt_want(b) tt_want_msg( (b), "want("#b")") #define tt_want(b) tt_want_msg((b), "want(" #b ")")
/* Assert b, and stop the test if b fails. */ /* Assert b, and stop the test if b fails. */
#define tt_assert(b) tt_assert_msg((b), "assert("#b")") #define tt_assert(b) tt_assert_msg((b), "assert(" #b ")")
#define tt_assert_test_fmt_type(a,b,str_test,type,test,printf_type,printf_fmt, \ #define tt_assert_test_fmt_type(a, b, str_test, type, test, printf_type, \
setup_block,cleanup_block,die_on_fail) \ printf_fmt, setup_block, cleanup_block, \
die_on_fail) \
TT_STMT_BEGIN \ TT_STMT_BEGIN \
type val1_ = (a); \ type val1_ = (a); \
type val2_ = (b); \ type val2_ = (b); \
int tt_status_ = (test); \ int tt_status_ = (test); \
if (!tt_status_ || tinytest_get_verbosity_()>1) { \ if (!tt_status_ || tinytest_get_verbosity_() > 1) { \
printf_type print_; \ printf_type print_; \
printf_type print1_; \ printf_type print1_; \
printf_type print2_; \ printf_type print2_; \
@@ -126,84 +132,88 @@
value_ = val2_; \ value_ = val2_; \
setup_block; \ setup_block; \
print2_ = print_; \ print2_ = print_; \
TT_DECLARE(tt_status_?" OK":"FAIL", \ TT_DECLARE(tt_status_ ? " OK" : "FAIL", \
("assert(%s): " printf_fmt " vs " printf_fmt,\ ("assert(%s): " printf_fmt " vs " printf_fmt, str_test, \
str_test, print1_, print2_)); \ print1_, print2_)); \
print_ = print1_; \ print_ = print1_; \
cleanup_block; \ cleanup_block; \
print_ = print2_; \ print_ = print2_; \
cleanup_block; \ cleanup_block; \
if (!tt_status_) { \ if (!tt_status_) { \
tinytest_set_test_failed_(); \ tinytest_set_test_failed_(); \
die_on_fail ; \ die_on_fail; \
} \ } \
} \ } \
TT_STMT_END TT_STMT_END
#define tt_assert_test_type(a,b,str_test,type,test,fmt,die_on_fail) \ #define tt_assert_test_type(a, b, str_test, type, test, fmt, die_on_fail) \
tt_assert_test_fmt_type(a,b,str_test,type,test,type,fmt, \ tt_assert_test_fmt_type(a, b, str_test, type, test, type, fmt, \
{print_=value_;},{},die_on_fail) { print_ = value_; }, {}, die_on_fail)
#define tt_assert_test_type_opt(a,b,str_test,type,test,fmt,die_on_fail) \ #define tt_assert_test_type_opt(a, b, str_test, type, test, fmt, die_on_fail) \
tt_assert_test_fmt_type(a,b,str_test,type,test,type,fmt, \ tt_assert_test_fmt_type(a, b, str_test, type, test, type, fmt, \
{print_=value_?value_:"<NULL>";},{},die_on_fail) { print_ = value_ ? value_ : "<NULL>"; }, {}, \
die_on_fail)
/* Helper: assert that a op b, when cast to type. Format the values with /* Helper: assert that a op b, when cast to type. Format the values with
* printf format fmt on failure. */ * printf format fmt on failure. */
#define tt_assert_op_type(a,op,b,type,fmt) \ #define tt_assert_op_type(a, op, b, type, fmt) \
tt_assert_test_type(a,b,#a" "#op" "#b,type,(val1_ op val2_),fmt, \ tt_assert_test_type(a, b, #a " " #op " " #b, type, (val1_ op val2_), fmt, \
TT_EXIT_TEST_FUNCTION) TT_EXIT_TEST_FUNCTION)
#define tt_int_op(a,op,b) \ #define tt_int_op(a, op, b) \
tt_assert_test_type(a,b,#a" "#op" "#b,long,(val1_ op val2_), \ tt_assert_test_type(a, b, #a " " #op " " #b, long, (val1_ op val2_), "%ld", \
"%ld",TT_EXIT_TEST_FUNCTION)
#define tt_uint_op(a,op,b) \
tt_assert_test_type(a,b,#a" "#op" "#b,unsigned long, \
(val1_ op val2_),"%lu",TT_EXIT_TEST_FUNCTION)
#define tt_ptr_op(a,op,b) \
tt_assert_test_type(a,b,#a" "#op" "#b,const void*, \
(val1_ op val2_),"%p",TT_EXIT_TEST_FUNCTION)
#define tt_str_op(a,op,b) \
tt_assert_test_type_opt(a,b,#a" "#op" "#b,const char *, \
(val1_ && val2_ && strcmp(val1_,val2_) op 0),"<%s>", \
TT_EXIT_TEST_FUNCTION) TT_EXIT_TEST_FUNCTION)
#define tt_uint_op(a, op, b) \
tt_assert_test_type(a, b, #a " " #op " " #b, unsigned long, \
(val1_ op val2_), "%lu", TT_EXIT_TEST_FUNCTION)
#define tt_ptr_op(a, op, b) \
tt_assert_test_type(a, b, #a " " #op " " #b, const void *, (val1_ op val2_), \
"%p", TT_EXIT_TEST_FUNCTION)
#define tt_str_op(a, op, b) \
tt_assert_test_type_opt(a, b, #a " " #op " " #b, const char *, \
(val1_ && val2_ && strcmp(val1_, val2_) op 0), \
"<%s>", TT_EXIT_TEST_FUNCTION)
#define tt_mem_op(expr1, op, expr2, len) \ #define tt_mem_op(expr1, op, expr2, len) \
tt_assert_test_fmt_type(expr1,expr2,#expr1" "#op" "#expr2, \ tt_assert_test_fmt_type( \
const void *, \ expr1, expr2, #expr1 " " #op " " #expr2, const void *, \
(val1_ && val2_ && memcmp(val1_, val2_, len) op 0), \ (val1_ && val2_ && memcmp(val1_, val2_, len) op 0), char *, "%s", \
char *, "%s", \
{ print_ = tinytest_format_hex_(value_, (len)); }, \ { print_ = tinytest_format_hex_(value_, (len)); }, \
{ if (print_) free(print_); }, \ { \
TT_EXIT_TEST_FUNCTION \ if (print_) \
); free(print_); \
}, \
TT_EXIT_TEST_FUNCTION);
#define tt_want_int_op(a,op,b) \ #define tt_want_int_op(a, op, b) \
tt_assert_test_type(a,b,#a" "#op" "#b,long,(val1_ op val2_),"%ld",(void)0) tt_assert_test_type(a, b, #a " " #op " " #b, long, (val1_ op val2_), "%ld", \
(void)0)
#define tt_want_uint_op(a,op,b) \ #define tt_want_uint_op(a, op, b) \
tt_assert_test_type(a,b,#a" "#op" "#b,unsigned long, \ tt_assert_test_type(a, b, #a " " #op " " #b, unsigned long, \
(val1_ op val2_),"%lu",(void)0) (val1_ op val2_), "%lu", (void)0)
#define tt_want_ptr_op(a,op,b) \ #define tt_want_ptr_op(a, op, b) \
tt_assert_test_type(a,b,#a" "#op" "#b,const void*, \ tt_assert_test_type(a, b, #a " " #op " " #b, const void *, (val1_ op val2_), \
(val1_ op val2_),"%p",(void)0) "%p", (void)0)
#define tt_want_str_op(a,op,b) \ #define tt_want_str_op(a, op, b) \
tt_assert_test_type(a,b,#a" "#op" "#b,const char *, \ tt_assert_test_type(a, b, #a " " #op " " #b, const char *, \
(strcmp(val1_,val2_) op 0),"<%s>",(void)0) (strcmp(val1_, val2_) op 0), "<%s>", (void)0)
#define tt_want_mem_op(expr1, op, expr2, len) \ #define tt_want_mem_op(expr1, op, expr2, len) \
tt_assert_test_fmt_type(expr1,expr2,#expr1" "#op" "#expr2, \ tt_assert_test_fmt_type( \
const void *, \ expr1, expr2, #expr1 " " #op " " #expr2, const void *, \
(val1_ && val2_ && memcmp(val1_, val2_, len) op 0), \ (val1_ && val2_ && memcmp(val1_, val2_, len) op 0), char *, "%s", \
char *, "%s", \
{ print_ = tinytest_format_hex_(value_, (len)); }, \ { print_ = tinytest_format_hex_(value_, (len)); }, \
{ if (print_) free(print_); }, \ { \
(void)0 \ if (print_) \
); free(print_); \
}, \
(void)0);
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,8 @@
* To Public License, Version 2, as published by Sam Hocevar. See * To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details. * http://sam.zoy.org/wtfpl/COPYING for more details.
* *
* I2P-Bote: 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV * I2P-Bote:
* 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV
* we are the Borg. */ * we are the Borg. */
#ifndef LIBSAM3_H #ifndef LIBSAM3_H
#define LIBSAM3_H #define LIBSAM3_H
@@ -20,7 +21,6 @@ extern "C" {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
extern int libsam3_debug; extern int libsam3_debug;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#define SAM3_HOST_DEFAULT (NULL) #define SAM3_HOST_DEFAULT (NULL)
#define SAM3_PORT_DEFAULT (0) #define SAM3_PORT_DEFAULT (0)
@@ -28,43 +28,47 @@ extern int libsam3_debug;
#define SAM3_DESTINATION_TRANSIENT (NULL) #define SAM3_DESTINATION_TRANSIENT (NULL)
#define SAM3_PUBKEY_SIZE (516) #define SAM3_PUBKEY_SIZE (516)
#define SAM3_PRIVKEY_SIZE (884) #define SAM3_CERT_SIZE (100)
#define SAM3_PRIVKEY_MIN_SIZE (884)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/* returns fd or -1 */ /* returns fd or -1 */
/* 'ip': host IP; can be NULL */ /* 'ip': host IP; can be NULL */
extern int sam3tcpConnect (const char *hostname, int port, uint32_t *ip); extern int sam3tcpConnect(const char *hostname, int port, uint32_t *ip);
extern int sam3tcpConnectIP (uint32_t ip, int port); extern int sam3tcpConnectIP(uint32_t ip, int port);
/* <0: error; 0: ok */ /* <0: error; 0: ok */
extern int sam3tcpDisconnect (int fd); extern int sam3tcpDisconnect(int fd);
/* <0: error; 0: ok */ /* <0: error; 0: ok */
extern int sam3tcpSetTimeoutSend (int fd, int timeoutms); extern int sam3tcpSetTimeoutSend(int fd, int timeoutms);
/* <0: error; 0: ok */ /* <0: error; 0: ok */
extern int sam3tcpSetTimeoutReceive (int fd, int timeoutms); extern int sam3tcpSetTimeoutReceive(int fd, int timeoutms);
/* <0: error; 0: ok */ /* <0: error; 0: ok */
/* sends the whole buffer */ /* sends the whole buffer */
extern int sam3tcpSend (int fd, const void *buf, size_t bufSize); extern int sam3tcpSend(int fd, const void *buf, size_t bufSize);
/* <0: received (-res) bytes; read error */ /* <0: received (-res) bytes; read error */
/* can return less that requesten bytes even if `allowPartial` is 0 when connection is closed */ /* can return less that requesten bytes even if `allowPartial` is 0 when
extern ssize_t sam3tcpReceiveEx (int fd, void *buf, size_t bufSize, int allowPartial); * connection is closed */
extern ssize_t sam3tcpReceiveEx(int fd, void *buf, size_t bufSize,
int allowPartial);
extern ssize_t sam3tcpReceive (int fd, void *buf, size_t bufSize); extern ssize_t sam3tcpReceive(int fd, void *buf, size_t bufSize);
extern int sam3tcpPrintf (int fd, const char *fmt, ...) __attribute__((format(printf,2,3))); extern int sam3tcpPrintf(int fd, const char *fmt, ...)
__attribute__((format(printf, 2, 3)));
extern int sam3tcpReceiveStr (int fd, char *dest, size_t maxSize); extern int sam3tcpReceiveStr(int fd, char *dest, size_t maxSize);
/* pass NULL for 'localhost' and 0 for 7655 */ /* pass NULL for 'localhost' and 0 for 7655 */
/* 'ip': host IP; can be NULL */ /* 'ip': host IP; can be NULL */
extern int sam3udpSendTo (const char *hostname, int port, const void *buf, size_t bufSize, uint32_t *ip); extern int sam3udpSendTo(const char *hostname, int port, const void *buf,
extern int sam3udpSendToIP (uint32_t ip, int port, const void *buf, size_t bufSize); size_t bufSize, uint32_t *ip);
extern int sam3udpSendToIP(uint32_t ip, int port, const void *buf,
size_t bufSize);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
typedef struct SAMFieldList { typedef struct SAMFieldList {
@@ -73,16 +77,16 @@ typedef struct SAMFieldList {
struct SAMFieldList *next; struct SAMFieldList *next;
} SAMFieldList; } SAMFieldList;
extern void sam3FreeFieldList(SAMFieldList *list);
extern void sam3FreeFieldList (SAMFieldList *list); extern void sam3DumpFieldList(const SAMFieldList *list);
extern void sam3DumpFieldList (const SAMFieldList *list);
/* read and parse SAM reply */ /* read and parse SAM reply */
/* NULL: error; else: list of fields */ /* NULL: error; else: list of fields */
/* first item is always 2-word reply, with first word in name and second in value */ /* first item is always 2-word reply, with first word in name and second in
extern SAMFieldList *sam3ReadReply (int fd); * value */
extern SAMFieldList *sam3ReadReply(int fd);
extern SAMFieldList *sam3ParseReply (const char *rep); extern SAMFieldList *sam3ParseReply(const char *rep);
/* /*
* example: * example:
@@ -92,17 +96,17 @@ extern SAMFieldList *sam3ParseReply (const char *rep);
* VALUE: NULL or 'OK' * VALUE: NULL or 'OK'
* returns bool * returns bool
*/ */
extern int sam3IsGoodReply (const SAMFieldList *list, const char *r0, const char *r1, const char *field, const char *value); extern int sam3IsGoodReply(const SAMFieldList *list, const char *r0,
const char *r1, const char *field,
extern const char *sam3FindField (const SAMFieldList *list, const char *field); const char *value);
extern const char *sam3FindField(const SAMFieldList *list, const char *field);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/* pass NULL for 'localhost' and 0 for 7656 */ /* pass NULL for 'localhost' and 0 for 7656 */
/* returns <0 on error or socket fd on success */ /* returns <0 on error or socket fd on success */
extern int sam3Handshake (const char *hostname, int port, uint32_t *ip); extern int sam3Handshake(const char *hostname, int port, uint32_t *ip);
extern int sam3HandshakeIP (uint32_t ip, int port); extern int sam3HandshakeIP(uint32_t ip, int port);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
typedef enum { typedef enum {
@@ -111,14 +115,25 @@ typedef enum {
SAM3_SESSION_STREAM SAM3_SESSION_STREAM
} Sam3SessionType; } Sam3SessionType;
typedef enum {
DSA_SHA1,
ECDSA_SHA256_P256,
ECDSA_SHA384_P384,
ECDSA_SHA512_P521,
EdDSA_SHA512_Ed25519
} Sam3SigType;
typedef struct Sam3Session { typedef struct Sam3Session {
Sam3SessionType type; Sam3SessionType type;
Sam3SigType sigType;
int fd; int fd;
char privkey[SAM3_PRIVKEY_SIZE+1]; // destination private key (asciiz) char privkey[SAM3_PRIVKEY_MIN_SIZE + 1]; // destination private key (asciiz)
char pubkey[SAM3_PUBKEY_SIZE+1]; // destination public key (asciiz) char pubkey[SAM3_PUBKEY_SIZE + SAM3_CERT_SIZE +
1]; // destination public key (asciiz)
char channel[66]; // name of this sam session (asciiz) char channel[66]; // name of this sam session (asciiz)
char destkey[SAM3_PUBKEY_SIZE+1]; // for DGRAM sessions (asciiz) char destkey[SAM3_PUBKEY_SIZE + SAM3_CERT_SIZE +
1]; // for DGRAM sessions (asciiz)
// int destsig;
char error[32]; // error message (asciiz) char error[32]; // error message (asciiz)
uint32_t ip; uint32_t ip;
int port; // this will be changed to UDP port for DRAM/RAW (can be 0) int port; // this will be changed to UDP port for DRAM/RAW (can be 0)
@@ -126,12 +141,13 @@ typedef struct Sam3Session {
int fwd_fd; int fwd_fd;
} Sam3Session; } Sam3Session;
typedef struct Sam3Connection { typedef struct Sam3Connection {
Sam3Session *ses; Sam3Session *ses;
struct Sam3Connection *next; struct Sam3Connection *next;
int fd; int fd;
char destkey[SAM3_PUBKEY_SIZE+1]; // remote destination public key (asciiz) char destkey[SAM3_PUBKEY_SIZE + SAM3_CERT_SIZE +
1]; // remote destination public key (asciiz)
int destcert;
char error[32]; // error message (asciiz) char error[32]; // error message (asciiz)
} Sam3Connection; } Sam3Connection;
@@ -144,19 +160,26 @@ typedef struct Sam3Connection {
* 'params' can be NULL * 'params' can be NULL
* see http://www.i2p2.i2p/i2cp.html#options for common options, * see http://www.i2p2.i2p/i2cp.html#options for common options,
* and http://www.i2p2.i2p/streaming.html#options for STREAM 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: error, 'ses' fields are undefined, no need to call
* if result==0: ok, all 'ses' fields are filled * sam3CloseSession() if result==0: ok, all 'ses' fields are filled
* TODO: don't clear 'error' field on error (and set it to something meaningful) * TODO: don't clear 'error' field on error (and set it to something meaningful)
*/ */
extern int sam3CreateSession (Sam3Session *ses, const char *hostname, int port, const char *privkey, Sam3SessionType type, extern int sam3CreateSession(Sam3Session *ses, const char *hostname, int port,
const char *params); const char *privkey, Sam3SessionType type,
Sam3SigType sigType, const char *params);
/* /*
* close SAM session (and all it's connections) * close SAM session (and all it's connections)
* returns <0 on error, 0 on ok * returns <0 on error, 0 on ok
* 'ses' must be properly initialized * 'ses' must be properly initialized
*/ */
extern int sam3CloseSession (Sam3Session *ses); extern int sam3CloseSession(Sam3Session *ses);
/*
* Check to make sure that the destination in use is of a valid length, returns
* 1 if true and 0 if false.
*/
int sam3CheckValidKeyLength(const char *pubkey);
/* /*
* open stream connection to 'destkey' endpoint * open stream connection to 'destkey' endpoint
@@ -165,7 +188,7 @@ extern int sam3CloseSession (Sam3Session *ses);
* you still have to call sam3CloseSession() on failure * you still have to call sam3CloseSession() on failure
* sets ses->error on error * sets ses->error on error
*/ */
extern Sam3Connection *sam3StreamConnect (Sam3Session *ses, const char *destkey); extern Sam3Connection *sam3StreamConnect(Sam3Session *ses, const char *destkey);
/* /*
* accepts stream connection and sets 'destkey' * accepts stream connection and sets 'destkey'
@@ -175,7 +198,7 @@ extern Sam3Connection *sam3StreamConnect (Sam3Session *ses, const char *destkey)
* sets ses->error on error * sets ses->error on error
* note that there is no timeouts for now, but you can use sam3tcpSetTimeout*() * note that there is no timeouts for now, but you can use sam3tcpSetTimeout*()
*/ */
extern Sam3Connection *sam3StreamAccept (Sam3Session *ses); extern Sam3Connection *sam3StreamAccept(Sam3Session *ses);
/* /*
* sets up forwarding stream connection * sets up forwarding stream connection
@@ -184,7 +207,7 @@ extern Sam3Connection *sam3StreamAccept (Sam3Session *ses);
* sets ses->error on error * sets ses->error on error
* note that there is no timeouts for now, but you can use sam3tcpSetTimeout*() * note that there is no timeouts for now, but you can use sam3tcpSetTimeout*()
*/ */
extern int sam3StreamForward (Sam3Session *ses, const char *hostname, int port); extern int sam3StreamForward(Sam3Session *ses, const char *hostname, int port);
/* /*
* close SAM connection * close SAM connection
@@ -192,8 +215,7 @@ extern int sam3StreamForward (Sam3Session *ses, const char *hostname, int port);
* 'conn' must be properly initialized * 'conn' must be properly initialized
* 'conn' is invalid after call * 'conn' is invalid after call
*/ */
extern int sam3CloseConnection (Sam3Connection *conn); extern int sam3CloseConnection(Sam3Connection *conn);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/* /*
@@ -203,7 +225,8 @@ extern int sam3CloseConnection (Sam3Connection *conn);
* will not set 'error' field * will not set 'error' field
* returns <0 on error, 0 on ok * returns <0 on error, 0 on ok
*/ */
extern int sam3GenerateKeys (Sam3Session *ses, const char *hostname, int port); extern int sam3GenerateKeys(Sam3Session *ses, const char *hostname, int port,
int sigType);
/* /*
* do name lookup (something like gethostbyname()) * do name lookup (something like gethostbyname())
@@ -212,8 +235,8 @@ extern int sam3GenerateKeys (Sam3Session *ses, const char *hostname, int port);
* will set 'error' field * will set 'error' field
* returns <0 on error, 0 on ok * returns <0 on error, 0 on ok
*/ */
extern int sam3NameLookup (Sam3Session *ses, const char *hostname, int port, const char *name); extern int sam3NameLookup(Sam3Session *ses, const char *hostname, int port,
const char *name);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/* /*
@@ -224,32 +247,34 @@ extern int sam3NameLookup (Sam3Session *ses, const char *hostname, int port, con
* sets ses->error on error * sets ses->error on error
* don't send datagrams bigger than 31KB! * don't send datagrams bigger than 31KB!
*/ */
extern int sam3DatagramSend (Sam3Session *ses, const char *destkey, const void *buf, size_t bufsize); extern int sam3DatagramSend(Sam3Session *ses, const char *destkey,
const void *buf, size_t bufsize);
/* /*
* receives datagram and sets 'destkey' to source pubkey (if not RAW) * receives datagram and sets 'destkey' to source pubkey (if not RAW)
* returns <0 on error (buffer too small is error too) or number of bytes written to 'buf' * returns <0 on error (buffer too small is error too) or number of bytes
* you still have to call sam3CloseSession() on failure * written to 'buf' you still have to call sam3CloseSession() on failure sets
* sets ses->error on error * ses->error on error will necer receive datagrams bigger than 31KB (32KB for
* will necer receive datagrams bigger than 31KB (32KB for RAW) * RAW)
*/ */
extern ssize_t sam3DatagramReceive (Sam3Session *ses, void *buf, size_t bufsize); extern ssize_t sam3DatagramReceive(Sam3Session *ses, void *buf, size_t bufsize);
/* /*
* generate random sam channel name * generate random sam channel name
* return the size of the string * return the size of the string
*/ */
extern size_t sam3GenChannelName (char *dest, size_t minlen, size_t maxlen); extern size_t sam3GenChannelName(char *dest, size_t minlen, size_t maxlen);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// NOT including '\0' terminator // NOT including '\0' terminator
static inline size_t sam3Base32EncodedLength (size_t size) { return (((size+5-1)/5)*8); } static inline size_t sam3Base32EncodedLength(size_t size) {
return (((size + 5 - 1) / 5) * 8);
}
// output 8 bytes for every 5 input // output 8 bytes for every 5 input
// return size or <0 on error // return size or <0 on error
extern ssize_t sam3Base32Encode (char *dest, size_t destsz, const void *srcbuf, size_t srcsize); extern ssize_t sam3Base32Encode(char *dest, size_t destsz, const void *srcbuf,
size_t srcsize);
#ifdef __cplusplus #ifdef __cplusplus
} }

File diff suppressed because it is too large Load Diff

View File

@@ -6,7 +6,8 @@
* To Public License, Version 2, as published by Sam Hocevar. See * To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details. * http://sam.zoy.org/wtfpl/COPYING for more details.
* *
* I2P-Bote: 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV * I2P-Bote:
* 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV
* we are the Borg. */ * we are the Borg. */
#ifndef LIBSAM3A_H #ifndef LIBSAM3A_H
#define LIBSAM3A_H #define LIBSAM3A_H
@@ -32,7 +33,6 @@ extern "C" {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
extern int libsam3a_debug; extern int libsam3a_debug;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#define SAM3A_HOST_DEFAULT (NULL) #define SAM3A_HOST_DEFAULT (NULL)
#define SAM3A_PORT_DEFAULT (0) #define SAM3A_PORT_DEFAULT (0)
@@ -42,16 +42,13 @@ extern int libsam3a_debug;
#define SAM3A_PUBKEY_SIZE (516) #define SAM3A_PUBKEY_SIZE (516)
#define SAM3A_PRIVKEY_SIZE (884) #define SAM3A_PRIVKEY_SIZE (884)
////////////////////////////////////////////////////////////////////////////////
extern uint64_t sam3atimeval2ms(const struct timeval *tv);
extern void sam3ams2timeval(struct timeval *tv, uint64_t ms);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
extern uint64_t sam3atimeval2ms (const struct timeval *tv); extern int sam3aIsValidPubKey(const char *key);
extern void sam3ams2timeval (struct timeval *tv, uint64_t ms); extern int sam3aIsValidPrivKey(const char *key);
////////////////////////////////////////////////////////////////////////////////
extern int sam3aIsValidPubKey (const char *key);
extern int sam3aIsValidPrivKey (const char *key);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
typedef struct Sam3ASession Sam3ASession; typedef struct Sam3ASession Sam3ASession;
@@ -79,22 +76,26 @@ typedef struct {
/** session callback functions */ /** session callback functions */
typedef struct { typedef struct {
void (*cbError) (Sam3ASession *ses); /** called on error */ void (*cbError)(Sam3ASession *ses); /** called on error */
void (*cbCreated) (Sam3ASession *ses); /** called when we created the session */ void (*cbCreated)(
void (*cbDisconnected) (Sam3ASession *ses); /* call when closed; will called only after cbCreated() */ Sam3ASession *ses); /** called when we created the session */
void (*cbDatagramRead) (Sam3ASession *ses, const void *buf, int bufsize); /* called when we got a datagram; bufsize >= 0; destkey set */ void (*cbDisconnected)(Sam3ASession *ses); /* call when closed; will called
void (*cbDestroy) (Sam3ASession *ses); /* called when fd is already closed, but keys is not cleared */ only after cbCreated() */
void (*cbDatagramRead)(Sam3ASession *ses, const void *buf,
int bufsize); /* called when we got a datagram; bufsize
>= 0; destkey set */
void (*cbDestroy)(Sam3ASession *ses); /* called when fd is already closed, but
keys is not cleared */
} Sam3ASessionCallbacks; } Sam3ASessionCallbacks;
struct Sam3ASession { struct Sam3ASession {
Sam3ASessionType type; /** session type */ Sam3ASessionType type; /** session type */
int fd; /** socket file descriptor */ int fd; /** socket file descriptor */
int cancelled; /** fd was shutdown()ed, but not closed yet */ int cancelled; /** fd was shutdown()ed, but not closed yet */
char privkey[SAM3A_PRIVKEY_SIZE+1]; /** private key (asciiz) */ char privkey[SAM3A_PRIVKEY_SIZE + 1]; /** private key (asciiz) */
char pubkey[SAM3A_PUBKEY_SIZE+1]; /** public key (asciiz) */ char pubkey[SAM3A_PUBKEY_SIZE + 1]; /** public key (asciiz) */
char channel[66]; /** channel name (asciiz) */ char channel[66]; /** channel name (asciiz) */
char destkey[SAM3A_PUBKEY_SIZE+1]; /** for DGRAM sessions (asciiz) */ char destkey[SAM3A_PUBKEY_SIZE + 1]; /** for DGRAM sessions (asciiz) */
char error[64]; /** error message (asciiz) */ char error[64]; /** error message (asciiz) */
uint32_t ip; /** ipv4 address of sam api interface */ uint32_t ip; /** ipv4 address of sam api interface */
int port; /** UDP port for DRAM/RAW (can be 0) */ int port; /** UDP port for DRAM/RAW (can be 0) */
@@ -103,8 +104,8 @@ struct Sam3ASession {
/** begin internal members */ /** begin internal members */
// for async i/o // for async i/o
Sam3AIO aio; Sam3AIO aio;
void (*cbAIOProcessorR) (Sam3ASession *ses); // internal void (*cbAIOProcessorR)(Sam3ASession *ses); // internal
void (*cbAIOProcessorW) (Sam3ASession *ses); // internal void (*cbAIOProcessorW)(Sam3ASession *ses); // internal
int callDisconnectCB; int callDisconnectCB;
char *params; // will be cleared only by sam3aCloseSession() char *params; // will be cleared only by sam3aCloseSession()
int timeoutms; int timeoutms;
@@ -118,22 +119,24 @@ struct Sam3ASession {
/** connection callbacks for data sockets */ /** connection callbacks for data sockets */
typedef struct { typedef struct {
/** called on error */ /** called on error */
void (*cbError) (Sam3AConnection *ct); void (*cbError)(Sam3AConnection *ct);
/** called when closed or only after cbConnected()/cbAccepted(); note that force disconnect is ok */ /** called when closed or only after cbConnected()/cbAccepted(); note that
void (*cbDisconnected) (Sam3AConnection *ct); * force disconnect is ok */
void (*cbDisconnected)(Sam3AConnection *ct);
/** called when connected */ /** called when connected */
void (*cbConnected) (Sam3AConnection *ct); void (*cbConnected)(Sam3AConnection *ct);
/** called instead of cbConnected() for sam3aStreamAccept*(), destkey filled with remote destination */ /** called instead of cbConnected() for sam3aStreamAccept*(), destkey filled
void (*cbAccepted) (Sam3AConnection *ct); * with remote destination */
/** send callback, data sent, can add new data; will be called after connect/accept */ void (*cbAccepted)(Sam3AConnection *ct);
void (*cbSent) (Sam3AConnection *ct); /** send callback, data sent, can add new data; will be called after
* connect/accept */
void (*cbSent)(Sam3AConnection *ct);
/** read callback, data read from socket (bufsize is always > 0) */ /** read callback, data read from socket (bufsize is always > 0) */
void (*cbRead) (Sam3AConnection *ct, const void *buf, int bufsize); void (*cbRead)(Sam3AConnection *ct, const void *buf, int bufsize);
/** fd already closed, but keys is not cleared */ /** fd already closed, but keys is not cleared */
void (*cbDestroy) (Sam3AConnection *ct); void (*cbDestroy)(Sam3AConnection *ct);
} Sam3AConnectionCallbacks; } Sam3AConnectionCallbacks;
struct Sam3AConnection { struct Sam3AConnection {
/** parent session */ /** parent session */
Sam3ASession *ses; Sam3ASession *ses;
@@ -141,14 +144,14 @@ struct Sam3AConnection {
/** file descriptor */ /** file descriptor */
int fd; int fd;
int cancelled; // fd was shutdown()ed, but not closed yet int cancelled; // fd was shutdown()ed, but not closed yet
char destkey[SAM3A_PUBKEY_SIZE+1]; // (asciiz) char destkey[SAM3A_PUBKEY_SIZE + 1]; // (asciiz)
char error[32]; // (asciiz) char error[32]; // (asciiz)
/** begin internal members */ /** begin internal members */
// for async i/o // for async i/o
Sam3AIO aio; Sam3AIO aio;
void (*cbAIOProcessorR) (Sam3AConnection *ct); // internal void (*cbAIOProcessorR)(Sam3AConnection *ct); // internal
void (*cbAIOProcessorW) (Sam3AConnection *ct); // internal void (*cbAIOProcessorW)(Sam3AConnection *ct); // internal
int callDisconnectCB; int callDisconnectCB;
char *params; // will be cleared only by sam3aCloseConnection() char *params; // will be cleared only by sam3aCloseConnection()
int timeoutms; int timeoutms;
@@ -160,20 +163,18 @@ struct Sam3AConnection {
void *udata; void *udata;
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/* /*
* check if session is active (i.e. have opened socket) * check if session is active (i.e. have opened socket)
* returns bool * returns bool
*/ */
extern int sam3aIsActiveSession (const Sam3ASession *ses); extern int sam3aIsActiveSession(const Sam3ASession *ses);
/* /*
* check if connection is active (i.e. have opened socket) * check if connection is active (i.e. have opened socket)
* returns bool * returns bool
*/ */
extern int sam3aIsActiveConnection (const Sam3AConnection *conn); extern int sam3aIsActiveConnection(const Sam3AConnection *conn);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/* /*
@@ -188,35 +189,40 @@ extern int sam3aIsActiveConnection (const Sam3AConnection *conn);
* 'params' can be NULL * 'params' can be NULL
* see http://www.i2p2.i2p/i2cp.html#options for common options, * see http://www.i2p2.i2p/i2cp.html#options for common options,
* and http://www.i2p2.i2p/streaming.html#options for STREAM options * and http://www.i2p2.i2p/streaming.html#options for STREAM options
* if result<0: error, 'ses' fields are undefined, no need to call sam3aCloseSession() * if result<0: error, 'ses' fields are undefined, no need to call
* if result==0: ok, all 'ses' fields are filled * sam3aCloseSession() if result==0: ok, all 'ses' fields are filled
* TODO: don't clear 'error' field on error (and set it to something meaningful) * TODO: don't clear 'error' field on error (and set it to something meaningful)
*/ */
extern int sam3aCreateSessionEx (Sam3ASession *ses, const Sam3ASessionCallbacks *cb, extern int sam3aCreateSessionEx(Sam3ASession *ses,
const char *hostname, int port, const char *privkey, Sam3ASessionType type, const char *params, int timeoutms); const Sam3ASessionCallbacks *cb,
const char *hostname, int port,
const char *privkey, Sam3ASessionType type,
const char *params, int timeoutms);
static inline int sam3aCreateSession (Sam3ASession *ses, const Sam3ASessionCallbacks *cb, static inline int sam3aCreateSession(Sam3ASession *ses,
const char *hostname, int port, const char *privkey, Sam3ASessionType type) const Sam3ASessionCallbacks *cb,
{ const char *hostname, int port,
const char *privkey,
Sam3ASessionType type) {
return sam3aCreateSessionEx(ses, cb, hostname, port, privkey, type, NULL, -1); return sam3aCreateSessionEx(ses, cb, hostname, port, privkey, type, NULL, -1);
} }
/* returns <0 on error, 0 if no, >0 if yes */ /* returns <0 on error, 0 if no, >0 if yes */
extern int sam3aIsHaveActiveConnections (const Sam3ASession *ses); extern int sam3aIsHaveActiveConnections(const Sam3ASession *ses);
/* /*
* close SAM session (and all it's connections) * close SAM session (and all it's connections)
* returns <0 on error, 0 on ok * returns <0 on error, 0 on ok
* 'ses' must be properly initialized * 'ses' must be properly initialized
*/ */
extern int sam3aCloseSession (Sam3ASession *ses); extern int sam3aCloseSession(Sam3ASession *ses);
/* /*
* cancel SAM session (and all it's connections), but don't free() or clear anything except fds * cancel SAM session (and all it's connections), but don't free() or clear
* returns <0 on error, 0 on ok * anything except fds returns <0 on error, 0 on ok 'ses' must be properly
* 'ses' must be properly initialized * initialized
*/ */
extern int sam3aCancelSession (Sam3ASession *ses); extern int sam3aCancelSession(Sam3ASession *ses);
/* /*
* open stream connection to 'destkey' endpoint * open stream connection to 'destkey' endpoint
@@ -224,10 +230,14 @@ extern int sam3aCancelSession (Sam3ASession *ses);
* returns <0 on error * returns <0 on error
* sets ses->error on memory or socket creation error * sets ses->error on memory or socket creation error
*/ */
extern Sam3AConnection *sam3aStreamConnectEx (Sam3ASession *ses, const Sam3AConnectionCallbacks *cb, const char *destkey, extern Sam3AConnection *sam3aStreamConnectEx(Sam3ASession *ses,
const Sam3AConnectionCallbacks *cb,
const char *destkey,
int timeoutms); int timeoutms);
static inline Sam3AConnection *sam3aStreamConnect (Sam3ASession *ses, const Sam3AConnectionCallbacks *cb, const char *destkey) { static inline Sam3AConnection *
sam3aStreamConnect(Sam3ASession *ses, const Sam3AConnectionCallbacks *cb,
const char *destkey) {
return sam3aStreamConnectEx(ses, cb, destkey, -1); return sam3aStreamConnectEx(ses, cb, destkey, -1);
} }
@@ -239,9 +249,12 @@ static inline Sam3AConnection *sam3aStreamConnect (Sam3ASession *ses, const Sam3
* sets ses->error on error * sets ses->error on error
* note that there is no timeouts for now, but you can use sam3atcpSetTimeout*() * note that there is no timeouts for now, but you can use sam3atcpSetTimeout*()
*/ */
extern Sam3AConnection *sam3aStreamAcceptEx (Sam3ASession *ses, const Sam3AConnectionCallbacks *cb, int timeoutms); extern Sam3AConnection *sam3aStreamAcceptEx(Sam3ASession *ses,
const Sam3AConnectionCallbacks *cb,
int timeoutms);
static inline Sam3AConnection *sam3aStreamAccept (Sam3ASession *ses, const Sam3AConnectionCallbacks *cb) { static inline Sam3AConnection *
sam3aStreamAccept(Sam3ASession *ses, const Sam3AConnectionCallbacks *cb) {
return sam3aStreamAcceptEx(ses, cb, -1); return sam3aStreamAcceptEx(ses, cb, -1);
} }
@@ -251,7 +264,7 @@ static inline Sam3AConnection *sam3aStreamAccept (Sam3ASession *ses, const Sam3A
* 'conn' must be properly initialized * 'conn' must be properly initialized
* 'conn' is invalid after call * 'conn' is invalid after call
*/ */
extern int sam3aCloseConnection (Sam3AConnection *conn); extern int sam3aCloseConnection(Sam3AConnection *conn);
/* /*
* cancel SAM connection, but don't free() or clear anything except fd * cancel SAM connection, but don't free() or clear anything except fd
@@ -259,8 +272,7 @@ extern int sam3aCloseConnection (Sam3AConnection *conn);
* 'conn' must be properly initialized * 'conn' must be properly initialized
* 'conn' is invalid after call * 'conn' is invalid after call
*/ */
extern int sam3aCancelConnection (Sam3AConnection *conn); extern int sam3aCancelConnection(Sam3AConnection *conn);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/* /*
@@ -269,7 +281,7 @@ extern int sam3aCancelConnection (Sam3AConnection *conn);
* *
* return: <0: error; 0: ok * return: <0: error; 0: ok
*/ */
extern int sam3aSend (Sam3AConnection *conn, const void *data, int datasize); extern int sam3aSend(Sam3AConnection *conn, const void *data, int datasize);
/* /*
* sends datagram to 'destkey' endpoint * sends datagram to 'destkey' endpoint
@@ -279,16 +291,15 @@ extern int sam3aSend (Sam3AConnection *conn, const void *data, int datasize);
* sets ses->error on error * sets ses->error on error
* don't send datagrams bigger than 31KB! * don't send datagrams bigger than 31KB!
*/ */
extern int sam3aDatagramSend (Sam3ASession *ses, const char *destkey, const void *buf, int bufsize); extern int sam3aDatagramSend(Sam3ASession *ses, const char *destkey,
const void *buf, int bufsize);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/* /*
* generate random channel name * generate random channel name
* dest should be at least (maxlen+1) bytes big * dest should be at least (maxlen+1) bytes big
*/ */
extern int sam3aGenChannelName (char *dest, int minlen, int maxlen); extern int sam3aGenChannelName(char *dest, int minlen, int maxlen);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/* /*
@@ -298,27 +309,31 @@ extern int sam3aGenChannelName (char *dest, int minlen, int maxlen);
* cbCreated callback will be called when keys generated * cbCreated callback will be called when keys generated
* returns <0 on error, 0 on ok * returns <0 on error, 0 on ok
*/ */
extern int sam3aGenerateKeysEx (Sam3ASession *ses, const Sam3ASessionCallbacks *cb, const char *hostname, int port, extern int sam3aGenerateKeysEx(Sam3ASession *ses,
int timeoutms); const Sam3ASessionCallbacks *cb,
const char *hostname, int port, int timeoutms);
static inline int sam3aGenerateKeys (Sam3ASession *ses, const Sam3ASessionCallbacks *cb, const char *hostname, int port) { static inline int sam3aGenerateKeys(Sam3ASession *ses,
const Sam3ASessionCallbacks *cb,
const char *hostname, int port) {
return sam3aGenerateKeysEx(ses, cb, hostname, port, -1); return sam3aGenerateKeysEx(ses, cb, hostname, port, -1);
} }
/* /*
* do name lookup (something like gethostbyname()) * do name lookup (something like gethostbyname())
* fills 'destkey' only * fills 'destkey' only
* you should call sam3aCloseSession() on 'ses' * you should call sam3aCloseSession() on 'ses'
* cbCreated callback will be called when keys generated, ses->destkey will be set * cbCreated callback will be called when keys generated, ses->destkey will be
* returns <0 on error, 0 on ok * set returns <0 on error, 0 on ok
*/ */
extern int sam3aNameLookupEx (Sam3ASession *ses, const Sam3ASessionCallbacks *cb, const char *hostname, int port, extern int sam3aNameLookupEx(Sam3ASession *ses, const Sam3ASessionCallbacks *cb,
const char *name, int timeoutms); const char *hostname, int port, const char *name,
int timeoutms);
static inline int sam3aNameLookup (Sam3ASession *ses, const Sam3ASessionCallbacks *cb, const char *hostname, int port, static inline int sam3aNameLookup(Sam3ASession *ses,
const char *name) const Sam3ASessionCallbacks *cb,
{ const char *hostname, int port,
const char *name) {
return sam3aNameLookupEx(ses, cb, hostname, port, name, -1); return sam3aNameLookupEx(ses, cb, hostname, port, name, -1);
} }
@@ -330,20 +345,20 @@ static inline int sam3aNameLookup (Sam3ASession *ses, const Sam3ASessionCallback
* returns maxfd or -1 * returns maxfd or -1
* TODO: should keep fd count so it will not exceed FD_SETSIZE! * TODO: should keep fd count so it will not exceed FD_SETSIZE!
*/ */
extern int sam3aAddSessionToFDS (Sam3ASession *ses, int maxfd, fd_set *rds, fd_set *wrs); extern int sam3aAddSessionToFDS(Sam3ASession *ses, int maxfd, fd_set *rds,
fd_set *wrs);
/* /*
* process session i/o (and all session connections i/o) * process session i/o (and all session connections i/o)
* should be called after successful select() * should be called after successful select()
*/ */
extern void sam3aProcessSessionIO (Sam3ASession *ses, fd_set *rds, fd_set *wrs); extern void sam3aProcessSessionIO(Sam3ASession *ses, fd_set *rds, fd_set *wrs);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/* return malloc()ed buffer and len in 'plen' (if plen != NULL) */ /* return malloc()ed buffer and len in 'plen' (if plen != NULL) */
extern char *sam3PrintfVA (int *plen, const char *fmt, va_list app); extern char *sam3PrintfVA(int *plen, const char *fmt, va_list app);
extern char *sam3Printf (int *plen, const char *fmt, ...) __attribute__((format(printf,2,3))); extern char *sam3Printf(int *plen, const char *fmt, ...)
__attribute__((format(printf, 2, 3)));
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -4,7 +4,8 @@
* To Public License, Version 2, as published by Sam Hocevar. See * To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details. * http://sam.zoy.org/wtfpl/COPYING for more details.
* *
* I2P-Bote: 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV * I2P-Bote:
* 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV
* we are the Borg. */ * we are the Borg. */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -15,8 +16,7 @@
#include "../../src/ext/tinytest_macros.h" #include "../../src/ext/tinytest_macros.h"
#include "../../src/libsam3/libsam3.h" #include "../../src/libsam3/libsam3.h"
static int testb32(const char *src, const char *res) {
static int testb32 (const char *src, const char *res) {
size_t dlen = sam3Base32EncodedLength(strlen(src)), len; size_t dlen = sam3Base32EncodedLength(strlen(src)), len;
char dest[128]; char dest[128];
// //
@@ -41,11 +41,11 @@ void test_b32_encode(void *data) {
tt_assert(testb32("fooba", "mzxw6ytb")); tt_assert(testb32("fooba", "mzxw6ytb"));
tt_assert(testb32("foobar", "mzxw6ytboi======")); tt_assert(testb32("foobar", "mzxw6ytboi======"));
end: end:;
;
} }
struct testcase_t b32_tests[] = { struct testcase_t b32_tests[] = {{
{ "encode", test_b32_encode, }, "encode",
END_OF_TESTCASES test_b32_encode,
}; },
END_OF_TESTCASES};

View File

@@ -5,10 +5,7 @@
extern struct testcase_t b32_tests[]; extern struct testcase_t b32_tests[];
struct testgroup_t test_groups[] = { struct testgroup_t test_groups[] = {{"b32/", b32_tests}, END_OF_GROUPS};
{ "b32/", b32_tests },
END_OF_GROUPS
};
int main(int argc, const char **argv) { int main(int argc, const char **argv) {
return tinytest_main(argc, argv, test_groups); return tinytest_main(argc, argv, test_groups);