Skip to content

Commit 1631251

Browse files
author
Felix Fietkau
committed
add client example code
Signed-off-by: Felix Fietkau <[email protected]>
1 parent 5bdc435 commit 1631251

File tree

3 files changed

+123
-1
lines changed

3 files changed

+123
-1
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ CMakeFiles
66
*.so
77
*.dylib
88
install_manifest.txt
9-
*-example
9+
ustream-example-client
10+
ustream-example-server

CMakeLists.txt

+3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ TARGET_LINK_LIBRARIES(ustream-ssl ubox ${SSL_LIB})
3535
ADD_EXECUTABLE(ustream-example-server ustream-example-server.c)
3636
TARGET_LINK_LIBRARIES(ustream-example-server ustream-ssl)
3737

38+
ADD_EXECUTABLE(ustream-example-client ustream-example-client.c)
39+
TARGET_LINK_LIBRARIES(ustream-example-client ustream-ssl)
40+
3841
INSTALL(FILES ustream-ssl.h
3942
DESTINATION include/libubox
4043
)

ustream-example-client.c

+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <unistd.h>
4+
5+
#include <libubox/usock.h>
6+
#include <libubox/uloop.h>
7+
#include "ustream-ssl.h"
8+
9+
static struct uloop_fd fd;
10+
11+
static struct ustream_fd stream, s_input;
12+
static struct ustream_ssl ssl;
13+
14+
static void *ctx;
15+
16+
static void client_teardown(void)
17+
{
18+
if (s_input.fd.registered)
19+
ustream_free(&s_input.stream);
20+
21+
ustream_free(&ssl.stream);
22+
ustream_free(&stream.stream);
23+
close(stream.fd.fd);
24+
uloop_end();
25+
}
26+
27+
static void client_input_notify_read(struct ustream *s, int bytes)
28+
{
29+
char *buf;
30+
int len;
31+
32+
buf = ustream_get_read_buf(s, &len);
33+
ustream_write(&ssl.stream, buf, len, false);
34+
ustream_consume(s, len);
35+
}
36+
37+
static void client_ssl_notify_read(struct ustream *s, int bytes)
38+
{
39+
char *buf;
40+
int len;
41+
42+
buf = ustream_get_read_buf(s, &len);
43+
fwrite(buf, len, 1, stdout);
44+
fflush(stdout);
45+
ustream_consume(s, len);
46+
}
47+
48+
static void client_notify_connected(struct ustream_ssl *ssl)
49+
{
50+
fprintf(stderr, "SSL connection established\n");
51+
s_input.stream.notify_read = client_input_notify_read;
52+
ustream_fd_init(&s_input, 0);
53+
}
54+
55+
static void client_notify_error(struct ustream_ssl *ssl, int error, const char *str)
56+
{
57+
fprintf(stderr, "SSL connection error(%d): %s\n", error, str);
58+
client_teardown();
59+
}
60+
61+
static void client_notify_state(struct ustream *us)
62+
{
63+
if (!us->write_error && !us->eof)
64+
return;
65+
66+
fprintf(stderr, "Connection closed\n");
67+
client_teardown();
68+
}
69+
70+
static void example_connect_ssl(int fd)
71+
{
72+
fprintf(stderr, "Starting SSL negnotiation\n");
73+
74+
ssl.notify_error = client_notify_error;
75+
ssl.notify_connected = client_notify_connected;
76+
ssl.stream.notify_read = client_ssl_notify_read;
77+
ssl.stream.notify_state = client_notify_state;
78+
79+
ustream_fd_init(&stream, fd);
80+
ustream_ssl_init(&ssl, &stream.stream, ctx, false);
81+
}
82+
83+
static void example_connect_cb(struct uloop_fd *f, unsigned int events)
84+
{
85+
if (fd.eof || fd.error) {
86+
fprintf(stderr, "Connection failed\n");
87+
uloop_end();
88+
return;
89+
}
90+
91+
fprintf(stderr, "Connection established\n");
92+
uloop_fd_delete(&fd);
93+
example_connect_ssl(fd.fd);
94+
}
95+
96+
static void connect_client(const char *host, const char *port)
97+
{
98+
fd.fd = usock(USOCK_TCP | USOCK_NONBLOCK, host, port);
99+
fd.cb = example_connect_cb;
100+
uloop_fd_add(&fd, ULOOP_WRITE | ULOOP_EDGE_TRIGGER);
101+
}
102+
103+
int main(int argc, char **argv)
104+
{
105+
if (argc != 3) {
106+
fprintf(stderr, "Usage: %s <hostname> <port>\n", argv[0]);
107+
return 1;
108+
}
109+
110+
ctx = ustream_ssl_context_new(false);
111+
uloop_init();
112+
connect_client(argv[1], argv[2]);
113+
uloop_run();
114+
115+
close(fd.fd);
116+
uloop_done();
117+
return 0;
118+
}

0 commit comments

Comments
 (0)