Add libwsclient_helper_socket function.

This function binds UNIX socket listener with specified path.
Any data received by this UNIX socket is sent out as a
WebSocket text frame.  This allows a user to send data
on behalf of a running libwsclient program.  Will add
some documentation for the entire library soon.  Will go
into depth there.
master
Payden Sutherland 12 years ago
parent 1ddfa42529
commit 05a0f6309c

@ -18,13 +18,12 @@ int onmessage(wsclient *c, wsclient_message *msg) {
}
int onopen(wsclient *c) {
fprintf(stderr, "onopen called.\n");
libwsclient_send(c, "testing::testing::demo.paydensutherland.com");
fprintf(stderr, "onopen called: %d\n", c->sockfd);
return 0;
}
int main(int argc, char **argv) {
wsclient *client = libwsclient_new("ws://ip6-localhost:8080");
wsclient *client = libwsclient_new("ws://websocket.mtgox.com/mtgox");
if(!client) {
fprintf(stderr, "Unable to initialize new WS client.\n");
exit(1);
@ -33,6 +32,7 @@ int main(int argc, char **argv) {
libwsclient_onmessage(client, &onmessage);
libwsclient_onerror(client, &onerror);
libwsclient_onclose(client, &onclose);
libwsclient_helper_socket(client, "test.sock");
libwsclient_run(client);
libwsclient_finish(client);
return 0;

@ -7,6 +7,7 @@
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <pthread.h>
@ -351,6 +352,88 @@ int libwsclient_open_connection(const char *host, const char *port) {
return sockfd;
}
int libwsclient_helper_socket(wsclient *c, const char *path) {
socklen_t len;
int sockfd;
if(c->helper_sa.sun_family) {
fprintf(stderr, "Can only bind one UNIX socket for helper program communications.\n");
return WS_HELPER_ALREADY_BOUND_ERR;
}
c->helper_sa.sun_family = AF_UNIX;
strncpy(c->helper_sa.sun_path, path, sizeof(c->helper_sa.sun_path) - 1);
unlink(c->helper_sa.sun_path);
len = strlen(c->helper_sa.sun_path) + sizeof(c->helper_sa.sun_family);
sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
if(sockfd == -1) {
fprintf(stderr, "Error creating UNIX socket.\n");
return WS_HELPER_CREATE_SOCK_ERR;
}
if(bind(sockfd, (struct sockaddr *)&c->helper_sa, len) == -1) {
fprintf(stderr, "Error binding UNIX socket.\n");
perror("bind");
close(sockfd);
memset(&c->helper_sa, 0, sizeof(struct sockaddr_un));
return WS_HELPER_BIND_ERR;
}
if(listen(sockfd, 5) == -1) {
fprintf(stderr, "Error listening on UNIX socket.\n");
close(sockfd);
memset(&c->helper_sa, 0, sizeof(struct sockaddr_un));
return WS_HELPER_LISTEN_ERR;
}
c->helper_sock = sockfd;
pthread_create(&c->helper_thread, NULL, libwsclient_helper_socket_thread, (void *)c);
}
void *libwsclient_helper_socket_thread(void *ptr) {
wsclient *c = ptr;
struct sockaddr_un remote;
socklen_t len;
int remote_sock, n, payload_idx, payload_sz;
char recv_buf[HELPER_RECV_BUF_SIZE];
char *payload = NULL, *payload_tmp = NULL;
for(;;) { //TODO: some way to cleanly break this loop
len = sizeof(remote);
if((remote_sock = accept(c->helper_sock, (struct sockaddr *)&remote, &len)) == -1) {
continue;
}
payload_idx = 0;
payload = (char *)malloc(HELPER_RECV_BUF_SIZE);
memset(payload, 0, payload_sz);
payload_sz = HELPER_RECV_BUF_SIZE;
do {
memset(recv_buf, 0, HELPER_RECV_BUF_SIZE);
n = recv(remote_sock, recv_buf, HELPER_RECV_BUF_SIZE - 1, 0);
if(n > 0) {
if(n + payload_idx >= payload_sz) {
payload_tmp = payload;
payload_sz += HELPER_RECV_BUF_SIZE;
payload = (char *)realloc(payload, payload_sz);
if(!payload) {
payload = payload_tmp;
fprintf(stderr, "Unable to realloc, data sent will be truncated.\n");
break;
}
memset(payload + payload_idx, 0, payload_sz - payload_idx);
}
memcpy(payload + payload_idx, recv_buf, n);
payload_idx += n;
}
} while(n > 0);
close(remote_sock);
libwsclient_send(c, payload);
free(payload);
payload = NULL;
}
return NULL;
}
wsclient *libwsclient_new(const char *URI) {
wsclient *client = NULL;

@ -1,10 +1,14 @@
#include <stdint.h>
#include <pthread.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#ifndef WSCLIENT_H_
#define WSCLIENT_H_
#define FRAME_CHUNK_LENGTH 1024
#define HELPER_RECV_BUF_SIZE 1024
#define CLIENT_IS_SSL (1 << 0)
#define CLIENT_CONNECTING (1 << 1)
@ -41,6 +45,10 @@
#define WS_HANDSHAKE_NO_UPGRADE_ERR -16
#define WS_HANDSHAKE_NO_CONNECTION_ERR -17
#define WS_HANDSHAKE_BAD_ACCEPT_ERR -18
#define WS_HELPER_ALREADY_BOUND_ERR -19
#define WS_HELPER_CREATE_SOCK_ERR -20
#define WS_HELPER_BIND_ERR -21
#define WS_HELPER_LISTEN_ERR -22
typedef struct _wsclient_frame {
unsigned int fin;
@ -69,6 +77,7 @@ typedef struct _wsclient_error {
} wsclient_error;
typedef struct _wsclient {
pthread_t helper_thread;
pthread_t handshake_thread;
pthread_t run_thread;
pthread_mutex_t lock;
@ -80,6 +89,8 @@ typedef struct _wsclient {
int (*onerror)(struct _wsclient *, wsclient_error *err);
int (*onmessage)(struct _wsclient *, wsclient_message *msg);
wsclient_frame *current_frame;
struct sockaddr_un helper_sa;
int helper_sock;
} wsclient;
@ -100,6 +111,8 @@ void libwsclient_cleanup_frames(wsclient_frame *first);
void libwsclient_in_data(wsclient *c, char in);
void libwsclient_dispatch_message(wsclient *c, wsclient_frame *current);
void libwsclient_close(wsclient *c);
int libwsclient_helper_socket(wsclient *c, const char *path);
void *libwsclient_helper_socket_thread(void *ptr);
//Define errors
char *errors[] = {

Loading…
Cancel
Save