diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..14c3b03 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,3 @@ +AUTOMAKE_OPTIONS = foreign + +SUBDIRS = . vterm \ No newline at end of file diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..bdac9c3 --- /dev/null +++ b/configure.ac @@ -0,0 +1,59 @@ +# initialise autoconf and set up some basic information about the program we’re packaging +AC_INIT([antd-publishers], [0.1.0a], [xsang.le@gmail.com]) + +# We’re going to use automake for this project +# [subdir-objects] if needed +AM_INIT_AUTOMAKE() + +# dependencies +# C compiler +AC_PROG_CC +# libtool for linking +AC_PROG_LIBTOOL + +AC_DEFINE([_GNU_SOURCE], [1],[Use GNU source]) +# AC_CANONICAL_HOST is needed to access the 'host_os' variable + +# debug option +AC_ARG_ENABLE([debug], + [ --enable-debug Turn on debugging], + [case "${enableval}" in + yes) AC_DEFINE([DEBUG], [1],[Enable debug]) ;; + no) ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-debug]) ;; + esac],[debug=false]) + +AC_CANONICAL_HOST +build_linux=no +build_windows=no +build_mac=no +# Detect the target system +case "${host_os}" in + linux*) + AC_DEFINE([LINUX], [1],[Linux system]) + build_linux=yes + ;; + darwin*) + build_mac=yes + AC_DEFINE([MACOS], [1],[MacOS system]) + ;; + *) + AC_MSG_ERROR(["OS $host_os is not supported"]) + ;; +esac +# case for window: +# cygwin*|mingw*) +# build_windows=yes +# ;; +# Pass the conditionals to automake +AM_CONDITIONAL([LINUX], [test "$build_linux" = "yes"]) +AM_CONDITIONAL([WINDOWS], [test "$build_windows" = "yes"]) +AM_CONDITIONAL([OSX], [test "$build_mac" = "yes"]) + +# find a file called Makefile.in, substitute placeholders +# like @PACKAGE_VERSION@ with values like 0.1.0a, +# and write the results to Makefile. +AC_CONFIG_FILES([Makefile vterm/Makefile]) + +# output the script: +AC_OUTPUT \ No newline at end of file diff --git a/log.h b/log.h new file mode 100644 index 0000000..7638e84 --- /dev/null +++ b/log.h @@ -0,0 +1,19 @@ +#ifndef LOG_H +#define LOG_H + +#include + +#define LOG_INIT(m) do { \ + setlogmask (LOG_UPTO (LOG_NOTICE)); \ + openlog ((m), LOG_CONS | LOG_PID | LOG_NDELAY, LOG_USER); \ + } while(0) + +#ifdef DEBUG + #define LOG(m, a,...) syslog ((LOG_NOTICE),m "_log@[%s: %d]: " a "\n", __FILE__, \ + __LINE__, ##__VA_ARGS__) +#else + #define LOG(m, a,...) do{}while(0) +#endif +#define ERROR(m, a,...) syslog ((LOG_ERR),m "_error@[%s: %d]: " a "\n", __FILE__, \ + __LINE__, ##__VA_ARGS__) +#endif \ No newline at end of file diff --git a/tunnel.c b/tunnel.c new file mode 100644 index 0000000..15d888b --- /dev/null +++ b/tunnel.c @@ -0,0 +1,196 @@ + +#include +#include +#include +#include +#include +#include +#include + +#include "tunnel.h" + +#define MODULE_NAME "api" + + +static int msg_check_number(int fd, int number) +{ + int value; + if(read(fd,&value,sizeof(value)) == -1) + { + ERROR(MODULE_NAME, "Unable to read integer value: %s", strerror(errno)); + return -1; + } + if(number != value) + { + ERROR(MODULE_NAME, "Value mismatches: %04X, expected %04X", value, number); + return -1; + } + return 0; +} +static int msg_read_string(int fd, char* buffer, uint8_t max_length) +{ + uint8_t size; + if(read(fd,&size,sizeof(size)) == -1) + { + ERROR(MODULE_NAME, "Unable to read string size: %s", strerror(errno)); + return -1; + } + if(size > max_length) + { + ERROR(MODULE_NAME, "String length exceeds the maximal value of %d", max_length); + return -1; + } + if(read(fd,buffer,size) == -1) + { + ERROR(MODULE_NAME, "Unable to read string to buffer: %s", strerror(errno)); + return -1; + } + return 0; +} + +static uint8_t* msg_read_payload(int fd, int* size) +{ + uint8_t* data; + if(read(fd,size,sizeof(*size)) == -1) + { + ERROR(MODULE_NAME, "Unable to read payload data size: %s", strerror(errno)); + return NULL; + } + if(*size <= 0) + { + return NULL; + } + + data = (uint8_t*) malloc(*size); + if(data == NULL) + { + ERROR(MODULE_NAME, "Unable to allocate memory for payload data: %s", strerror(errno)); + return NULL; + } + if(read(fd,data,*size) == -1) + { + ERROR(MODULE_NAME, "Unable to read payload data to buffer: %s", strerror(errno)); + free(data); + return NULL; + } + return data; +} + + +int open_unix_socket(char* path) +{ + struct sockaddr_un address; + address.sun_family = AF_UNIX; + + (void) strncpy(address.sun_path, path, sizeof(address.sun_path)); + int fd = socket(AF_UNIX, SOCK_STREAM, 0); + if(fd == -1) + { + ERROR(MODULE_NAME, "Unable to create Unix domain socket: %s", strerror(errno)); + return -1; + } + if(connect(fd, (struct sockaddr*)(&address), sizeof(address)) == -1) + { + ERROR(MODULE_NAME, "Unable to connect to socket '%s': %s", address.sun_path, strerror(errno)); + return -1; + } + LOG(MODULE_NAME, "Socket %s is created successfully", path); + return fd; +} + + +int msg_read(int fd, tunnel_msg_t* msg) +{ + if(msg_check_number(fd, MSG_MAGIC_BEGIN) == -1) + { + ERROR(MODULE_NAME, "Unable to check begin magic number"); + return -1; + } + if(read(fd,&msg->header.type,sizeof(msg->header.type)) == -1) + { + ERROR(MODULE_NAME, "Unable to read msg type: %s", strerror(errno)); + return -1; + } + if(msg->header.type > 0x6) + { + ERROR(MODULE_NAME, "Unknown msg type: %d", msg->header.type); + return -1; + } + if(read(fd, &msg->header.channel_id, sizeof(msg->header.channel_id)) == -1) + { + ERROR(MODULE_NAME, "Unable to read msg channel id"); + return -1; + } + if(read(fd, &msg->header.client_id, sizeof(msg->header.client_id)) == -1) + { + ERROR(MODULE_NAME, "Unable to read msg client id"); + return -1; + } + if((msg->data = msg_read_payload(fd, &msg->header.size)) == NULL && msg->header.size != 0) + { + ERROR(MODULE_NAME, "Unable to read msg payload data"); + return -1; + } + if(msg_check_number(fd, MSG_MAGIC_END) == -1) + { + if(msg->data) + { + free(msg->data); + } + ERROR(MODULE_NAME, "Unable to check end magic number"); + return -1; + } + return 0; +} + +int msg_write(int fd, tunnel_msg_t* msg) +{ + // write begin magic number + int number = MSG_MAGIC_BEGIN; + if(write(fd,&number, sizeof(number)) == -1) + { + ERROR(MODULE_NAME, "Unable to write begin magic number: %s", strerror(errno)); + return -1; + } + // write type + if(write(fd,&msg->header.type, sizeof(msg->header.type)) == -1) + { + ERROR(MODULE_NAME, "Unable to write msg type: %s", strerror(errno)); + return -1; + } + // write channel id + if(write(fd,&msg->header.channel_id, sizeof(msg->header.channel_id)) == -1) + { + ERROR(MODULE_NAME, "Unable to write msg channel id: %s", strerror(errno)); + return -1; + } + //write client id + if(write(fd,&msg->header.client_id, sizeof(msg->header.client_id)) == -1) + { + ERROR(MODULE_NAME, "Unable to write msg client id: %s", strerror(errno)); + return -1; + } + // write payload len + + if(write(fd,&msg->header.size, sizeof(msg->header.size)) == -1) + { + ERROR(MODULE_NAME, "Unable to write msg payload length: %s", strerror(errno)); + return -1; + } + // write payload data + if(msg->header.size > 0) + { + if(write(fd,msg->data, msg->header.size) == -1) + { + ERROR(MODULE_NAME, "Unable to write msg payload: %s", strerror(errno)); + return -1; + } + } + number = MSG_MAGIC_END; + if(write(fd,&number, sizeof(number)) == -1) + { + ERROR(MODULE_NAME, "Unable to write end magic number: %s", strerror(errno)); + return -1; + } + return 0; +} \ No newline at end of file diff --git a/tunnel.h b/tunnel.h new file mode 100644 index 0000000..c86918f --- /dev/null +++ b/tunnel.h @@ -0,0 +1,36 @@ +#ifndef TUNNEL_H +#define TUNNEL_H +#include +#include "log.h" + +#define MAX_CHANNEL_PATH 108 +#define MAX_CHANNEL_NAME 64 + +#define MSG_MAGIC_BEGIN 0x414e5444 //ANTD +#define MSG_MAGIC_END 0x44544e41 //DTNA + +#define CHANNEL_OK (uint8_t)0x0 +#define CHANNEL_ERROR (uint8_t)0x1 +#define CHANNEL_OPEN (uint8_t)0x4 +#define CHANNEL_CLOSE (uint8_t)0x5 +#define CHANNEL_DATA (uint8_t)0x6 + +typedef struct { + uint8_t type; + int channel_id; + int client_id; + int size; +} tunnel_msg_h_t; + +typedef struct{ + tunnel_msg_h_t header; + uint8_t* data; +} tunnel_msg_t; + +int open_unix_socket(char* path); +int msg_write(int fd, tunnel_msg_t* msg); +int msg_read(int fd, tunnel_msg_t* msg); + + + +#endif \ No newline at end of file diff --git a/vterm/Makefile.am b/vterm/Makefile.am new file mode 100644 index 0000000..8fb610c --- /dev/null +++ b/vterm/Makefile.am @@ -0,0 +1,12 @@ +AUTOMAKE_OPTIONS = foreign + + + +AM_CPPFLAGS = -W -Wall -g -std=c99 + +# bin +bin_PROGRAMS = vterm +# source files +vterm_SOURCES = vterm.c ../tunnel.c +vterm_CPPFLAGS= -I../ +# antd_LDADD = libantd.la diff --git a/vterm/vterm b/vterm/vterm new file mode 100755 index 0000000..6c11645 Binary files /dev/null and b/vterm/vterm differ diff --git a/vterm/vterm.c b/vterm/vterm.c new file mode 100644 index 0000000..d0c02dd --- /dev/null +++ b/vterm/vterm.c @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include "tunnel.h" + +#define MODULE_NAME "vterm" + +int main(int argc, char** argv) +{ + int fd; + tunnel_msg_t msg; + int status; + char buff[MAX_CHANNEL_NAME+1]; + LOG_INIT(MODULE_NAME); + if(argc != 2) + { + printf("Usage: %s path/to/hotline/socket\n", argv[0]); + return -1; + } + LOG(MODULE_NAME, "Hotline is: %s", argv[1]); + // now try to request new channel from hotline + fd = open_unix_socket(argv[1]); + if(fd == -1) + { + ERROR(MODULE_NAME, "Unable to open the hotline: %s", argv[1]); + return -1; + } + msg.header.type = CHANNEL_OPEN; + msg.header.channel_id = 0; + msg.header.client_id = 0; + LOG(MODULE_NAME, "Request to open the channel %s", MODULE_NAME); + (void)strncpy(buff, MODULE_NAME,MAX_CHANNEL_NAME); + msg.header.size = strlen(buff); + msg.data = (uint8_t*) buff; + if(msg_write(fd, &msg) == -1) + { + ERROR(MODULE_NAME, "Unable to write message to hotline"); + (void) close(fd); + return -1; + } + LOG(MODULE_NAME, "Wait for comfirm creation of %s", MODULE_NAME); + // now wait for message + if(msg_read(fd, &msg) == -1) + { + ERROR(MODULE_NAME, "Unable to read message from hotline"); + (void) close(fd); + return -1; + } + if(msg.header.type == CHANNEL_OK) + { + LOG(MODULE_NAME, "Channel created: %s", MODULE_NAME); + if(msg.data) + free(msg.data); + } + // close the channel + LOG(MODULE_NAME, "Close the channel %s (%d)", MODULE_NAME, fd); + msg.header.type = CHANNEL_CLOSE; + msg.header.size = 0; + msg.data = NULL; + sleep(5); + if( msg_write(fd, &msg) == -1) + { + ERROR(MODULE_NAME, "Unable to request channel close"); + } + (void)msg_read(fd, &msg); + shutdown(fd, SHUT_WR); + (void) close(fd); + printf("Main application\n"); + return 0; +} \ No newline at end of file