From 6d5dd810664690f3e002144a67a6a940b238006b Mon Sep 17 00:00:00 2001 From: mpc <mpc> Date: Sun, 1 Aug 2004 02:38:14 +0000 Subject: [PATCH] added i2p-ping --- apps/sam/c/doc/todo.txt | 1 - apps/sam/c/doc/whatsnew.txt | 4 + apps/sam/c/examples/i2p-ping/Makefile | 34 ++++ apps/sam/c/examples/i2p-ping/i2p-ping.c | 221 ++++++++++++++++++++++++ apps/sam/c/examples/warhammer-dgram.c | 5 +- apps/sam/c/inc/sam.h | 18 +- apps/sam/c/src/sam.c | 15 +- 7 files changed, 279 insertions(+), 19 deletions(-) create mode 100644 apps/sam/c/examples/i2p-ping/Makefile create mode 100644 apps/sam/c/examples/i2p-ping/i2p-ping.c diff --git a/apps/sam/c/doc/todo.txt b/apps/sam/c/doc/todo.txt index 6dc2bef8f5..f8f1f6f4ce 100644 --- a/apps/sam/c/doc/todo.txt +++ b/apps/sam/c/doc/todo.txt @@ -5,5 +5,4 @@ I need to do these things: Anyone can help with these things: -* Fix the example dgram-client.c * Compile on as many platforms as possible diff --git a/apps/sam/c/doc/whatsnew.txt b/apps/sam/c/doc/whatsnew.txt index 55b564fc8e..851e59cb92 100644 --- a/apps/sam/c/doc/whatsnew.txt +++ b/apps/sam/c/doc/whatsnew.txt @@ -1,4 +1,8 @@ +/* vi:set ts=4: */ + v1.25 + * Removed the old broken examples and added more comments to + warhammer-dgram.c * Added support for sessions - now LibSAM can have multiple SAM sessions going at once (with different destinations) * Rewrote sendq functions to automatically send big packets, for better diff --git a/apps/sam/c/examples/i2p-ping/Makefile b/apps/sam/c/examples/i2p-ping/Makefile new file mode 100644 index 0000000000..96f6a8cafb --- /dev/null +++ b/apps/sam/c/examples/i2p-ping/Makefile @@ -0,0 +1,34 @@ +# +# This Makefile is compatible with GNU Make +# + +# +# Programs +# + +CC = gcc + +# +# Flags +# + +CFLAGS = -g -O2 -pipe -std=c99 -Wall +CFLAGS += -I../../inc -L../../lib +LIBS = -lsam + +# +# Build rules +# + +all: i2p-ping + +i2p-ping: + $(CC) $(CFLAGS) -o i2p-ping.o -c i2p-ping.c + $(CC) $(CFLAGS) -o i2p-ping i2p-ping.o $(LIBS) + +# +# Cleanup rules +# + +clean: + -rm -f *.o *.exe i2p-ping diff --git a/apps/sam/c/examples/i2p-ping/i2p-ping.c b/apps/sam/c/examples/i2p-ping/i2p-ping.c new file mode 100644 index 0000000000..1f230c4ae1 --- /dev/null +++ b/apps/sam/c/examples/i2p-ping/i2p-ping.c @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the author nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> +#include "sam.h" + +static void usage(); + +static void closeback(sam_sess_t *session, sam_sid_t stream_id, + samerr_t reason); +static void connectback(sam_sess_t *session, sam_sid_t stream_id, + sam_pubkey_t dest); +static void databack(sam_sess_t *session, sam_sid_t stream_id, void *data, + size_t size); +static void diedback(sam_sess_t *session); +static void logback(char *s); +static void namingback(char *name, sam_pubkey_t pubkey, samerr_t result); +static void statusback(sam_sess_t *session, sam_sid_t stream_id, + samerr_t result); + +bool gotdest = false; +sam_pubkey_t dest; +bool quiet = false; +samerr_t laststatus = SAM_NULL; +sam_sid_t laststream = 0; + +int main(int argc, char* argv[]) +{ + int ch; + int count = 1; /* number of times to ping */ + char *samhost = "localhost"; + uint16_t samport = 7656; + + while ((ch = getopt(argc, argv, "c:h:p:qv")) != -1) { + switch (ch) { + case 'c': /* packet count */ + count = atoi(optarg); + break; + case 'h': /* SAM host */ + samhost = optarg; + break; + case 'p': /* SAM port */ + samport = atoi(optarg); + break; + case 'q': /* quiet mode */ + quiet = true; + break; + case 'v': /* version */ + puts("$Id$"); + puts("Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>"); + return 0; + case '?': + default: + usage(); + return 0; + } + } + argc -= optind; + argv += optind; + if (argc == 0 || argc > 1) { /* they forgot to specify a ping target */ + fprintf(stderr, "Invalid number of targets\n"); + usage(); + return 1; + } + + /* Hook up the callback functions - required by LibSAM */ + sam_closeback = &closeback; + sam_connectback = &connectback; + sam_databack = &databack; + sam_diedback = &diedback; + sam_logback = &logback; + sam_namingback = &namingback; + sam_statusback = &statusback; + + sam_sess_t *session = NULL; /* set to NULL to have LibSAM do the malloc */ + session = sam_session_init(session); /* malloc and set defaults */ + samerr_t rc = sam_connect(session, samhost, samport, "TRANSIENT", + SAM_STREAM, 0); + if (rc != SAM_OK) { + fprintf(stderr, "SAM connection failed: %s\n", sam_strerror(rc)); + sam_session_free(&session); + return 1; + } + + if (strlen(argv[0]) == 516) { + memcpy(dest, argv[0], SAM_PUBKEY_LEN); + gotdest = true; + } else + sam_naming_lookup(session, argv[0]); + + while (!gotdest) /* just wait for the naming lookup to complete */ + sam_read_buffer(session); + + for (int i = 0; i < count; ++i) { + time_t start = time(0); + sam_sid_t sid = sam_stream_connect(session, dest); + while (laststream != sid && laststatus == SAM_NULL) + sam_read_buffer(session); /* wait for the connect */ + if (laststatus == SAM_OK) + sam_stream_close(session, laststream); + time_t finish = time(0); + laststream = 0; + if (laststatus == SAM_OK) { + printf("%s: %.0fs\n", argv[0], difftime(finish, start)); + } else { + printf("Ping failed: %s\n", sam_strerror(laststatus)); + } + laststatus = SAM_NULL; + } + + sam_close(session); + sam_session_free(&session); + return 0; +} + +void usage() +{ + puts("Ha! Help? You've got to be kidding!"); +} + +/* + * Connection closed + */ +static void closeback(sam_sess_t *session, sam_sid_t stream_id, samerr_t reason) +{ + fprintf(stderr, "Connection closed to stream %d: %s\n", stream_id, + sam_strerror(reason)); +} + +/* + * Someone connected to us - how dare they! + */ +static void connectback(sam_sess_t *session, sam_sid_t stream_id, + sam_pubkey_t dest) +{ + sam_stream_close(session, stream_id); +} + +/* + * A peer sent us some data - just ignore it + */ +static void databack(sam_sess_t *session, sam_sid_t stream_id, void *data, + size_t size) +{ + free(data); +} + +/* + * This is called whenever the SAM connection fails (like if the I2P router is + * shut down) + */ +static void diedback(sam_sess_t *session) +{ + fprintf(stderr, "Lost SAM connection!\n"); + exit(1); +} + +/* + * The logging callback prints any logging messages from LibSAM (typically + * errors) + */ +static void logback(char *s) +{ + if (!quiet) + fprintf(stderr, "LibSAM: %s\n", s); +} + +/* + * This is really hackish, but we know that we are only doing one lookup, so + * what the hell + */ +static void namingback(char *name, sam_pubkey_t pubkey, samerr_t result) +{ + if (result != SAM_OK) { + fprintf(stderr, "Naming lookup failed: %s\n", sam_strerror(result)); + exit(1); + } + memcpy(dest, pubkey, SAM_PUBKEY_LEN); + gotdest = true; +} + +/* + * Our connection attempt returned a result + */ +static void statusback(sam_sess_t *session, sam_sid_t stream_id, + samerr_t result) +{ + laststatus = result; + laststream = stream_id; +} diff --git a/apps/sam/c/examples/warhammer-dgram.c b/apps/sam/c/examples/warhammer-dgram.c index 40908f932f..0e29dcd949 100644 --- a/apps/sam/c/examples/warhammer-dgram.c +++ b/apps/sam/c/examples/warhammer-dgram.c @@ -43,7 +43,7 @@ * LibSAM callbacks - functions in our code that are called by LibSAM when * something happens */ -static void dgramback(const sam_sess_t *session, sam_pubkey_t dest, void *data, +static void dgramback(sam_sess_t *session, sam_pubkey_t dest, void *data, size_t size); static void diedback(sam_sess_t *session); static void logback(char *s); @@ -141,7 +141,7 @@ int main(int argc, char* argv[]) * When we receive some data from another peer, just ignore it. Denial of * service programs don't need input ;) */ -static void dgramback(const sam_sess_t *session, sam_pubkey_t dest, void *data, +static void dgramback(sam_sess_t *session, sam_pubkey_t dest, void *data, size_t size) { puts("Received a datagram (ignored)"); @@ -155,6 +155,7 @@ static void dgramback(const sam_sess_t *session, sam_pubkey_t dest, void *data, static void diedback(sam_sess_t *session) { fprintf(stderr, "Lost SAM connection!\n"); + /* high quality code would do a sam_session_free() here */ exit(1); } diff --git a/apps/sam/c/inc/sam.h b/apps/sam/c/inc/sam.h index a338661e3b..2f9ca885c4 100644 --- a/apps/sam/c/inc/sam.h +++ b/apps/sam/c/inc/sam.h @@ -90,11 +90,13 @@ typedef struct { } sam_sess_t; /* a SAM session */ typedef enum { /* see sam_strerror() for detailed descriptions of these */ + /* no error code - not used by me (you can use it in your program) */ + SAM_NULL = 0, /* error codes from SAM itself (SAM_OK is not an actual "error") */ SAM_OK, SAM_CANT_REACH_PEER, SAM_DUPLICATED_DEST, SAM_I2P_ERROR, SAM_INVALID_KEY, SAM_KEY_NOT_FOUND, SAM_PEER_NOT_FOUND, SAM_TIMEOUT, SAM_UNKNOWN, - /* error codes from libsam */ + /* error codes from LibSAM */ SAM_BAD_VERSION, SAM_CALLBACKS_UNSET, SAM_SOCKET_ERROR, SAM_TOO_BIG } samerr_t; @@ -127,14 +129,14 @@ extern sam_sid_t sam_stream_connect(sam_sess_t *session, extern samerr_t sam_stream_send(sam_sess_t *session, sam_sid_t stream_id, const void *data, size_t size); /* Stream commands - callbacks */ -extern void (*sam_closeback)(const sam_sess_t *session, sam_sid_t stream_id, +extern void (*sam_closeback)(sam_sess_t *session, sam_sid_t stream_id, samerr_t reason); -extern void (*sam_connectback)(const sam_sess_t *session, - sam_sid_t stream_id, sam_pubkey_t dest); -extern void (*sam_databack)(const sam_sess_t *session, sam_sid_t stream_id, +extern void (*sam_connectback)(sam_sess_t *session, sam_sid_t stream_id, + sam_pubkey_t dest); +extern void (*sam_databack)(sam_sess_t *session, sam_sid_t stream_id, void *data, size_t size); -extern void (*sam_statusback)(const sam_sess_t *session, - sam_sid_t stream_id, samerr_t result); +extern void (*sam_statusback)(sam_sess_t *session, sam_sid_t stream_id, + samerr_t result); /* Stream send queue (experimental) */ extern void sam_sendq_add(sam_sess_t *session, sam_sid_t stream_id, @@ -147,7 +149,7 @@ extern samerr_t sam_dgram_send(sam_sess_t *session, const sam_pubkey_t dest, const void *data, size_t size); /* Datagram commands - callbacks */ -extern void (*sam_dgramback)(const sam_sess_t *session, sam_pubkey_t dest, +extern void (*sam_dgramback)(sam_sess_t *session, sam_pubkey_t dest, void *data, size_t size); #ifdef __cplusplus diff --git a/apps/sam/c/src/sam.c b/apps/sam/c/src/sam.c index bc32282b62..4acb29bf09 100644 --- a/apps/sam/c/src/sam.c +++ b/apps/sam/c/src/sam.c @@ -56,26 +56,25 @@ static ssize_t sam_write(sam_sess_t *session, const void *buf, size_t n); * Note: if you add a new callback be sure to check for non-NULL in sam_connect */ /* a peer closed the connection */ -void (*sam_closeback)(const sam_sess_t *session, sam_sid_t stream_id, - samerr_t reason) = NULL; +void (*sam_closeback)(sam_sess_t *session, sam_sid_t stream_id, samerr_t reason) + = NULL; /* a peer connected to us */ -void (*sam_connectback)(const sam_sess_t *session, sam_sid_t stream_id, +void (*sam_connectback)(sam_sess_t *session, sam_sid_t stream_id, sam_pubkey_t dest) = NULL; /* a peer sent some stream data (`data' MUST be freed) */ -void (*sam_databack)(const sam_sess_t *session, sam_sid_t stream_id, void *data, +void (*sam_databack)(sam_sess_t *session, sam_sid_t stream_id, void *data, size_t size) = NULL; /* a peer sent some datagram data (`data' MUST be freed) */ -void (*sam_dgramback)(const sam_sess_t *session, sam_pubkey_t dest, void *data, +void (*sam_dgramback)(sam_sess_t *session, sam_pubkey_t dest, void *data, size_t size) = NULL; /* we lost the connection to the SAM host */ void (*sam_diedback)(sam_sess_t *session) = NULL; /* logging callback */ void (*sam_logback)(char *str) = NULL; /* naming lookup reply - `pubkey' will be NULL if `result' isn't SAM_OK */ -void (*sam_namingback)(char *name, sam_pubkey_t pubkey, - samerr_t result) = NULL; +void (*sam_namingback)(char *name, sam_pubkey_t pubkey, samerr_t result) = NULL; /* our connection to a peer has completed */ -void (*sam_statusback)(const sam_sess_t *session, sam_sid_t stream_id, +void (*sam_statusback)(sam_sess_t *session, sam_sid_t stream_id, samerr_t result) = NULL; /* -- GitLab