1

This is client code by using libwebsocket version 1.5

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <string.h>
#include <assert.h>
#include <signal.h>

#include <syslog.h>
#include <sys/time.h>
#include <unistd.h>

#include <libwebsockets.h>

static volatile int force_exit = 0;
static int state, command_received = 0, forked = 0;

#define MAX_ECHO_PAYLOAD 1400
#define LOCAL_RESOURCE_PATH "./"

struct per_session_data {
 unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + MAX_ECHO_PAYLOAD + LWS_SEND_BUFFER_POST_PADDING];
 unsigned int len;
};

//for temporary storing data from tcpdump
struct per_session_data data1;

static int callback_echo(struct libwebsocket_context *context, struct libwebsocket *wsi, enum libwebsocket_callback_reasons reason, void *user, void *in, size_t len)
{
 struct per_session_data *pss = (struct per_session_data *)user;
 int n;

 switch (reason) {

 /* when the callback is used for client operations --> */

 case LWS_CALLBACK_CLOSED:
 case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
  printf("Closed\n");
  state = 0;
  break;
 case LWS_CALLBACK_ESTABLISHED:
 case LWS_CALLBACK_CLIENT_ESTABLISHED:
  printf("Client connected\n");
  state = 2;
  break;

 /* we will receive our packet here*/
 case LWS_CALLBACK_RECEIVE:
 case LWS_CALLBACK_CLIENT_RECEIVE:
  printf("Rx from server: %s\n", (char *)in);
  if (!strcmp((char *)in, "tcpdump"))
  {
   command_received = 1;
  }
  break;

 /* we will send our packet here */
 case LWS_CALLBACK_CLIENT_WRITEABLE:
  printf("client writing to server\n");
  pss->len = sprintf((char *)&pss->buf[LWS_SEND_BUFFER_PRE_PADDING], "%s", data1.buf + LWS_SEND_BUFFER_PRE_PADDING);

  n = libwebsocket_write(wsi, &pss->buf[LWS_SEND_BUFFER_PRE_PADDING], pss->len, LWS_WRITE_TEXT);
  printf("Data: %s\n\n\n\n\n\n\n", &pss->buf[LWS_SEND_BUFFER_PRE_PADDING]);


  //error handling for write fail and partial writes
  if (n < 0) {
   printf("ERROR %d writing to socket, hanging up\n", n);
   return -1;
  }

  if (n < (int)pss->len) {
   printf("Partial write\n");
   return -1;
  }
  break;

 default:
  printf("default...\n");
  break;
 }

 return 0;
}


/* List of available protocols  */
static struct libwebsocket_protocols protocols[] = {
 {
  "default",  /* name */
  callback_echo,  /* callback */
  sizeof(struct per_session_data) /* per_session_data_size */
 },
 {
  NULL, NULL, 0  /* End of list */
 }
};

void sighandler(int sig)
{
 force_exit = 1;
}

int main(int argc, char **argv)
{
 //pipe stuff
 int pipe_fd[2];

 if (pipe(pipe_fd) < 0)
 {
  perror("PIPE:");
  exit(-1);
 }

 //for libwebsocket_service
 int n = 0;

 //test port can be overidden
 int port = 9000;
 struct libwebsocket_context *context;
 int opts = 0;

 char interface_name[128] = "";
 const char *interface = NULL;

 int use_ssl = 0;
 char ssl_cert[256] = LOCAL_RESOURCE_PATH"/libwebsockets-test-server.pem";
 char ssl_key[256] = LOCAL_RESOURCE_PATH"/libwebsockets-test-server.key.pem";

 int listen_port = 80;

 struct lws_context_creation_info info;
 char passphrase[256];
 char uri[256] = "/";
 char address[256], ads_port[256 + 30];

 //lws servicing time intervals
 int rate_us = 250000;
 unsigned int oldus = 0;

 struct libwebsocket *wsi;

 //should check this
 int debug_level = 2;

 memset(&info, 0, sizeof info);

 lwsl_notice("Built to support client operations\n");


 //re-configuring server ip and port here
 if (argc == 3)
 {
  strncpy(address, argv[1], sizeof(address) - 1);
  address[sizeof(address) - 1] = '\0';
  port = atoi(argv[2]);
 }
 else if (argc == 1)
 {
  strncpy(address, "localhost", sizeof(address) - 1);
  address[sizeof(address) - 1] = '\0';
  port = 9000;
 }
 else
 {
  printf("Try: ./client.exec <ip> <port>\n");
  exit(-1);
 }

 /* we will only try to log things according to our debug_level */
 setlogmask(LOG_UPTO (LOG_DEBUG));
 openlog("lwsts", 0, LOG_DAEMON);

 /* tell the library what debug level to emit and to send it to syslog */
 lws_set_log_level(debug_level, lwsl_emit_syslog);
 lwsl_notice("libwebsockets echo test - "
   "(C) Copyright 2010-2015 Andy Green <andy@warmcat.com> - "
   "licensed under LGPL2.1\n");

 lwsl_notice("Running in client mode\n");

 listen_port = CONTEXT_PORT_NO_LISTEN;

 lwsl_info("requiring server cert validation againts %s\n", ssl_cert);
 info.ssl_ca_filepath = ssl_cert;

 info.port = listen_port;
 info.iface = interface;
 info.protocols = protocols;

#ifndef LWS_NO_EXTENSIONS
 info.extensions = libwebsocket_get_internal_extensions();
#endif

 info.gid = -1;
 info.uid = -1;
 info.options = opts;

 context = libwebsocket_create_context(&info);
 if (context == NULL) {
  lwsl_err("libwebsocket init failed\n");
  return -1;
 }



 signal(SIGINT, sighandler);

 n = 0;

 while (n >= 0 && !force_exit) 
 {
  //do connect only once
  if (!state) {
   state = 1;
   printf("Client connecting to %s:%u....\n", address, port);

   address[sizeof(address) - 1] = '\0';
   sprintf(ads_port, "%s:%u", address, port & 65535);

   wsi = libwebsocket_client_connect(context, address, port, use_ssl, uri, ads_port, ads_port, NULL, -1);
   if (!wsi) {
    printf("Client failed to connect to %s:%u\n", address, port);
    goto bail;
   }
  }


  if (command_received == 1 && !forked)
  {
   printf("Going to fork\n");
   forked = 1;
   pid_t child_pid = fork();

   if (child_pid == -1)
   {
    perror("FORK:");
    exit(-1);
   }

   else if (child_pid == 0)
   {
    close(pipe_fd[0]);
    printf("Starting tcpdump\n");

    if (dup2(pipe_fd[1], 1) < 0)
    {
     perror("DUP2:");
     exit(-1);
    }
    
    //closing the connection to server for child
    libwebsocket_context_destroy(context);
    closelog();

    char *cmd[] = {"tcpdump", "-i", "any", NULL};

    if (execv("/usr/sbin/tcpdump", cmd) < 0)
    {
     perror("EXECV:");
     exit(-1);
    }
   }
  }
  
 /* if (forked == 1)
  {
   close(pipe_fd[1]);
  }
*/
  if (command_received == 1)
  {
   //stay here if the pipe is empty else try to read max 1400 bytes of data
   while ((data1.len  = read(pipe_fd[0], data1.buf + LWS_SEND_BUFFER_PRE_PADDING, 1400)) <= 0);
   //check if server wants any service

   //printf("%s\n\n\n\n\n\n\n", data1.buf + LWS_SEND_BUFFER_PRE_PADDING);
   libwebsocket_callback_on_writable(context, wsi);
  }

  //This fn times out every 10usec
  n = libwebsocket_service(context, 10);

 }

 //bail: jump from while loop also if connect fails
bail:
 libwebsocket_context_destroy(context);

 printf("libwebsockets-test-echo exited cleanly\n");
 closelog();

 return 0;
}

This is my server code by using socket.io

var io = require('socket.io')();
var middleware = require('socketio-wildcard')();

io.use(middleware);

io.on('connection', function(socket) {
  console.log('On socket connection')
  socket.on('*', function(event, data){
    console.log("---- Event ----- : " + JSON.stringify(event));
    console.log("---- Data ----- : " + JSON.stringify(data))
  });
});

io.listen(9000, 'localhost');

The client is unable to connect with server. when i tested client with strace it infinitely does receive as below

recv(8, "", 1, 0)                       = 0
recv(8, "", 1, 0)                       = 0
recv(8, "", 1, 0)                       = 0
.
.
.
.

Please point out my mistake. Any help is appreciated.

Thanks

0 Answers0