add client example code
authorFelix Fietkau <nbd@openwrt.org>
Sat, 15 Mar 2014 15:16:24 +0000 (16:16 +0100)
committerFelix Fietkau <nbd@openwrt.org>
Sat, 15 Mar 2014 15:16:24 +0000 (16:16 +0100)
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
.gitignore
CMakeLists.txt
ustream-example-client.c [new file with mode: 0644]

index 7be06189f1a56435b58c6218365858bd015bcae4..f1a162f0e8f0a9b90e61b59953eb35c46d3947f8 100644 (file)
@@ -6,4 +6,5 @@ CMakeFiles
 *.so
 *.dylib
 install_manifest.txt
-*-example
+ustream-example-client
+ustream-example-server
index 7e2ddf56b64476f3372fc5842648ab3fa3d9e983..f494f6d8da148e8b24586c72b58fae2a46e033da 100644 (file)
@@ -35,6 +35,9 @@ TARGET_LINK_LIBRARIES(ustream-ssl ubox ${SSL_LIB})
 ADD_EXECUTABLE(ustream-example-server ustream-example-server.c)
 TARGET_LINK_LIBRARIES(ustream-example-server ustream-ssl)
 
+ADD_EXECUTABLE(ustream-example-client ustream-example-client.c)
+TARGET_LINK_LIBRARIES(ustream-example-client ustream-ssl)
+
 INSTALL(FILES ustream-ssl.h
        DESTINATION include/libubox
 )
diff --git a/ustream-example-client.c b/ustream-example-client.c
new file mode 100644 (file)
index 0000000..a02815b
--- /dev/null
@@ -0,0 +1,118 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <libubox/usock.h>
+#include <libubox/uloop.h>
+#include "ustream-ssl.h"
+
+static struct uloop_fd fd;
+
+static struct ustream_fd stream, s_input;
+static struct ustream_ssl ssl;
+
+static void *ctx;
+
+static void client_teardown(void)
+{
+       if (s_input.fd.registered)
+               ustream_free(&s_input.stream);
+
+       ustream_free(&ssl.stream);
+       ustream_free(&stream.stream);
+       close(stream.fd.fd);
+       uloop_end();
+}
+
+static void client_input_notify_read(struct ustream *s, int bytes)
+{
+       char *buf;
+       int len;
+
+       buf = ustream_get_read_buf(s, &len);
+       ustream_write(&ssl.stream, buf, len, false);
+       ustream_consume(s, len);
+}
+
+static void client_ssl_notify_read(struct ustream *s, int bytes)
+{
+       char *buf;
+       int len;
+
+       buf = ustream_get_read_buf(s, &len);
+       fwrite(buf, len, 1, stdout);
+       fflush(stdout);
+       ustream_consume(s, len);
+}
+
+static void client_notify_connected(struct ustream_ssl *ssl)
+{
+       fprintf(stderr, "SSL connection established\n");
+       s_input.stream.notify_read = client_input_notify_read;
+       ustream_fd_init(&s_input, 0);
+}
+
+static void client_notify_error(struct ustream_ssl *ssl, int error, const char *str)
+{
+       fprintf(stderr, "SSL connection error(%d): %s\n", error, str);
+       client_teardown();
+}
+
+static void client_notify_state(struct ustream *us)
+{
+       if (!us->write_error && !us->eof)
+               return;
+
+       fprintf(stderr, "Connection closed\n");
+       client_teardown();
+}
+
+static void example_connect_ssl(int fd)
+{
+       fprintf(stderr, "Starting SSL negnotiation\n");
+
+       ssl.notify_error = client_notify_error;
+       ssl.notify_connected = client_notify_connected;
+       ssl.stream.notify_read = client_ssl_notify_read;
+       ssl.stream.notify_state = client_notify_state;
+
+       ustream_fd_init(&stream, fd);
+       ustream_ssl_init(&ssl, &stream.stream, ctx, false);
+}
+
+static void example_connect_cb(struct uloop_fd *f, unsigned int events)
+{
+       if (fd.eof || fd.error) {
+               fprintf(stderr, "Connection failed\n");
+               uloop_end();
+               return;
+       }
+
+       fprintf(stderr, "Connection established\n");
+       uloop_fd_delete(&fd);
+       example_connect_ssl(fd.fd);
+}
+
+static void connect_client(const char *host, const char *port)
+{
+       fd.fd = usock(USOCK_TCP | USOCK_NONBLOCK, host, port);
+       fd.cb = example_connect_cb;
+       uloop_fd_add(&fd, ULOOP_WRITE | ULOOP_EDGE_TRIGGER);
+}
+
+int main(int argc, char **argv)
+{
+       if (argc != 3) {
+               fprintf(stderr, "Usage: %s <hostname> <port>\n", argv[0]);
+               return 1;
+       }
+
+       ctx = ustream_ssl_context_new(false);
+       uloop_init();
+       connect_client(argv[1], argv[2]);
+       uloop_run();
+
+       close(fd.fd);
+       uloop_done();
+       return 0;
+}