examples and utils
parent
a0d0c6be30
commit
1e5e475bcb
|
@ -0,0 +1,23 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
nontapmsg() {
|
||||||
|
echo $*
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ $# -eq 0 ] ; then
|
||||||
|
SRC="*.c"
|
||||||
|
else
|
||||||
|
SRC="$*"
|
||||||
|
fi
|
||||||
|
|
||||||
|
for i in $SRC
|
||||||
|
do
|
||||||
|
BIN=$(echo ${i} | sed "s/.c$/.bin/")
|
||||||
|
if [ ! -f ${BIN} ] || [ $(stat -c "%X" ${BIN}) -lt $(stat -c "%X" ${i}) ]
|
||||||
|
then
|
||||||
|
nontapmsg "compiling ${BIN}"
|
||||||
|
# gcc $BIN.c ./lib/*.o -o $BIN -I../src -I ./lib/ -L../ -L./lib/ -lipc -Wall -g -Wextra
|
||||||
|
gcc -Wall -g -Wextra "${i}" -o "${BIN}" -I../src -L../ ../src/ipc.h -lipc
|
||||||
|
touch "${BIN}"
|
||||||
|
fi
|
||||||
|
done
|
|
@ -0,0 +1,27 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#include "../src/ipc.h"
|
||||||
|
|
||||||
|
int main(int argc, char * argv[])
|
||||||
|
{
|
||||||
|
SECURE_BUFFER_DECLARATION (char, buffer, 4096);
|
||||||
|
uint32_t msize = 0;
|
||||||
|
char *message = "coucou";
|
||||||
|
|
||||||
|
if (argc == 2) {
|
||||||
|
message = argv[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
msize = ipc_message_raw_serialize (buffer, 2, 42, message, strlen(message));
|
||||||
|
write (1, buffer, msize);
|
||||||
|
fflush (stdout);
|
||||||
|
|
||||||
|
// to wait for a response
|
||||||
|
sleep (1);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
#!/usr/bin/perl -w
|
||||||
|
use v5.14;
|
||||||
|
|
||||||
|
while(<>) {
|
||||||
|
chomp;
|
||||||
|
my @wl = split "_\+";
|
||||||
|
my @wl2 = map { ucfirst lc } @wl;
|
||||||
|
say join "", @wl2;
|
||||||
|
}
|
|
@ -4,10 +4,20 @@ nontapmsg() {
|
||||||
echo $*
|
echo $*
|
||||||
}
|
}
|
||||||
|
|
||||||
for i in *.c
|
if [ $# -eq 0 ] ; then
|
||||||
|
SRC="*.c"
|
||||||
|
else
|
||||||
|
SRC="$*"
|
||||||
|
fi
|
||||||
|
|
||||||
|
for i in $SRC
|
||||||
do
|
do
|
||||||
f=`echo $i | sed "s/.c$//"`
|
BIN=$(echo ${i} | sed "s/.c$/.bin/")
|
||||||
nontapmsg "compiling $f"
|
if [ ! -f ${BIN} ] || [ $(stat -c "%X" ${BIN}) -lt $(stat -c "%X" ${i}) ]
|
||||||
# gcc $f.c ./lib/*.o -o $f -I../src -I ./lib/ -L../ -L./lib/ -lipc -Wall -g -Wextra
|
then
|
||||||
gcc -Wall -g -Wextra $f.c -o $f -I../src -L../ ../src/ipc.h -lipc
|
nontapmsg "compiling ${BIN}"
|
||||||
|
# gcc $BIN.c ./lib/*.o -o $BIN -I../src -I ./lib/ -L../ -L./lib/ -lipc -Wall -g -Wextra
|
||||||
|
gcc -Wall -g -Wextra "${i}" -o "${BIN}" -I../src -L../ ../src/ipc.h -lipc
|
||||||
|
touch "${BIN}"
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include "../src/ipc.h"
|
||||||
|
#include "../src/usocket.h"
|
||||||
|
|
||||||
|
// This program opens a file then provide it to another running program.
|
||||||
|
// see examples/fd-exchange-receiving.c
|
||||||
|
|
||||||
|
int main(int argc, char * argv[])
|
||||||
|
{
|
||||||
|
if (argc != 2) {
|
||||||
|
fprintf (stderr, "usage: %s file", argv[0]);
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sock = 0;
|
||||||
|
int fd = 0;
|
||||||
|
|
||||||
|
T_PERROR_R (((fd = open (argv[1], O_CREAT | O_RDWR)) < 0), "cannot open the file", EXIT_FAILURE);
|
||||||
|
|
||||||
|
TIPC_P_Q (usock_connect (&sock, "SOCKET_FD_EXCHANGE_TEST"), "trying to connect to the unix socket", EXIT_FAILURE);
|
||||||
|
TIPC_P_Q (ipc_provide_fd (sock, fd), "cannot send the file descriptor", EXIT_FAILURE);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include "../src/ipc.h"
|
||||||
|
#include "../src/usocket.h"
|
||||||
|
|
||||||
|
// This program receives an open file descriptor from another running program.
|
||||||
|
// see examples/fd-exchange-providing.c
|
||||||
|
|
||||||
|
int main(int argc, char * argv[])
|
||||||
|
{
|
||||||
|
if (argc != 1) {
|
||||||
|
fprintf (stderr, "usage: %s", argv[0]);
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int usock = 0;
|
||||||
|
int usockclient = 0;
|
||||||
|
int fd = 0;
|
||||||
|
|
||||||
|
TIPC_P_Q (usock_init (&usock, "SOCKET_FD_EXCHANGE_TEST"), "trying to connect to the unix socket", EXIT_FAILURE);
|
||||||
|
TIPC_P_Q (usock_accept (usock, &usockclient), "cannot accept a client from the unix socket", EXIT_FAILURE);
|
||||||
|
TIPC_P_Q (ipc_receive_fd (usockclient, &fd), "cannot receive the file descriptor", EXIT_FAILURE);
|
||||||
|
|
||||||
|
T_PERROR_R ((write (fd, "coucou\n", 7) < 0), "cannot write a message in the file", EXIT_FAILURE);
|
||||||
|
T_PERROR_R ((close (fd) < 0), "cannot close the file descriptor", EXIT_FAILURE);
|
||||||
|
|
||||||
|
TIPC_P_Q (usock_close (usock), "cannot close the unix socket", EXIT_FAILURE);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
111
examples/pong.c
111
examples/pong.c
|
@ -13,77 +13,45 @@
|
||||||
fprintf(stderr, "error while %s: %s\n", msg, err);\
|
fprintf(stderr, "error while %s: %s\n", msg, err);\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void chomp (char *str, ssize_t len) {
|
||||||
|
if (str[len -1] == '\n') {
|
||||||
|
str[len -1] = '\0';
|
||||||
|
}
|
||||||
|
if (str[len -2] == '\n') {
|
||||||
|
str[len -2] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct ipc_connection_info *srv;
|
struct ipc_connection_info *srv;
|
||||||
|
|
||||||
void non_interactive (char *env[])
|
void non_interactive (char *env[])
|
||||||
{
|
{
|
||||||
struct ipc_message m;
|
SECURE_DECLARATION (struct ipc_message, m);
|
||||||
memset (&m, 0, sizeof (struct ipc_message));
|
|
||||||
|
|
||||||
enum ipc_errors ret;
|
|
||||||
|
|
||||||
// init service
|
// init service
|
||||||
ret = ipc_connection (env, srv, SERVICE_NAME);
|
TIPC_P_Q (ipc_connection (env, srv, SERVICE_NAME), "application connection", EXIT_FAILURE);
|
||||||
if (ret != IPC_ERROR_NONE) {
|
TIPC_P_Q (ipc_message_format_data (&m, 42, MSG, (ssize_t) strlen(MSG) +1), "message format data", EXIT_FAILURE);
|
||||||
handle_err("main", "ipc_application_connection < 0");
|
|
||||||
PRINTERR(ret, "application connection");
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf ("msg to send (%ld): %.*s\n", (ssize_t) strlen(MSG) +1, (int) strlen(MSG), MSG);
|
printf ("msg to send (%ld): %.*s\n", (ssize_t) strlen(MSG) +1, (int) strlen(MSG), MSG);
|
||||||
ret = ipc_message_format_data (&m, 42, MSG, (ssize_t) strlen(MSG) +1);
|
TIPC_P_Q (ipc_write (srv, &m), "application write", EXIT_FAILURE);
|
||||||
if (ret != IPC_ERROR_NONE) {
|
|
||||||
PRINTERR(ret, "message format data");
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// printf ("msg to send in the client: ");
|
|
||||||
// ipc_message_print (&m);
|
|
||||||
ret = ipc_write (srv, &m);
|
|
||||||
if (ret != IPC_ERROR_NONE) {
|
|
||||||
handle_err("main", "application_write");
|
|
||||||
PRINTERR(ret, "application write");
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
ipc_message_empty (&m);
|
ipc_message_empty (&m);
|
||||||
|
TIPC_P_Q (ipc_read (srv, &m), "application read", EXIT_FAILURE);
|
||||||
ret = ipc_read (srv, &m);
|
|
||||||
if (ret != IPC_ERROR_NONE) {
|
|
||||||
handle_err("main", "application_read");
|
|
||||||
PRINTERR(ret, "application read");
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf ("msg recv (type: %u): %s\n", m.user_type, m.payload);
|
printf ("msg recv (type: %u): %s\n", m.user_type, m.payload);
|
||||||
ipc_message_empty (&m);
|
ipc_message_empty (&m);
|
||||||
|
|
||||||
ret = ipc_close (srv);
|
TIPC_P_Q (ipc_close (srv), "application close", EXIT_FAILURE);
|
||||||
if (ret != IPC_ERROR_NONE) {
|
|
||||||
handle_err("main", "application_close");
|
|
||||||
PRINTERR(ret, "application close");
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void interactive (char *env[])
|
void interactive (char *env[])
|
||||||
{
|
{
|
||||||
enum ipc_errors ret;
|
|
||||||
|
|
||||||
// init service
|
// init service
|
||||||
ret = ipc_connection (env, srv, SERVICE_NAME);
|
TIPC_P_Q (ipc_connection (env, srv, SERVICE_NAME), "application connection", EXIT_FAILURE);
|
||||||
if (ret != IPC_ERROR_NONE) {
|
|
||||||
handle_err ("main", "ipc_application_connection < 0");
|
|
||||||
PRINTERR(ret, "application connection");
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ipc_event event;
|
SECURE_DECLARATION (struct ipc_event, event);
|
||||||
memset (&event, 0, sizeof (struct ipc_event));
|
SECURE_DECLARATION (struct ipc_connection_infos, services);
|
||||||
|
|
||||||
struct ipc_connection_infos services;
|
|
||||||
memset (&services, 0, sizeof (struct ipc_connection_infos));
|
|
||||||
ipc_add (&services, srv);
|
ipc_add (&services, srv);
|
||||||
|
|
||||||
ipc_add_fd (&services, 0); // add STDIN
|
ipc_add_fd (&services, 0); // add STDIN
|
||||||
|
|
||||||
ipc_connections_print (&services);
|
ipc_connections_print (&services);
|
||||||
|
@ -91,37 +59,33 @@ void interactive (char *env[])
|
||||||
while (1) {
|
while (1) {
|
||||||
printf ("msg to send: ");
|
printf ("msg to send: ");
|
||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
ret = ipc_wait_event (&services, NULL, &event);
|
|
||||||
|
|
||||||
if (ret != IPC_ERROR_NONE) {
|
TIPC_P_Q (ipc_wait_event (&services, NULL, &event), "wait event", EXIT_FAILURE);
|
||||||
PRINTERR(ret, "wait event");
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case IPC_EVENT_TYPE_EXTRA_SOCKET:
|
case IPC_EVENT_TYPE_EXTRA_SOCKET:
|
||||||
{
|
{
|
||||||
// structure not read, should read the message here
|
// structure not read, should read the message here
|
||||||
|
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
char buf[4096];
|
char buf[4096];
|
||||||
memset(buf, 0, 4096);
|
memset(buf, 0, 4096);
|
||||||
|
|
||||||
len = read (event.origin->fd, buf, 4096);
|
len = read (event.origin->fd, buf, 4096);
|
||||||
|
|
||||||
buf[100] = '\0';
|
buf[len -1] = '\0';
|
||||||
|
chomp (buf, len);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
printf ("\n");
|
||||||
|
printf ("message to send: %.*s\n", (int) len, buf);
|
||||||
|
#endif
|
||||||
|
|
||||||
// in case we want to quit the program
|
// in case we want to quit the program
|
||||||
if ( len == 0
|
if ( len == 0
|
||||||
|| strncmp (buf, "quit", 4) == 0
|
|| strncmp (buf, "quit", 4) == 0
|
||||||
|| strncmp (buf, "exit", 4) == 0) {
|
|| strncmp (buf, "exit", 4) == 0) {
|
||||||
|
|
||||||
ret = ipc_close (srv);
|
TIPC_P_Q (ipc_close (srv), "application close", EXIT_FAILURE);
|
||||||
if (ret != IPC_ERROR_NONE) {
|
|
||||||
handle_err("main", "ipc_close");
|
|
||||||
PRINTERR(ret, "application close");
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
ipc_connections_free (&services);
|
ipc_connections_free (&services);
|
||||||
|
|
||||||
|
@ -130,15 +94,18 @@ void interactive (char *env[])
|
||||||
|
|
||||||
// send the message read on STDIN
|
// send the message read on STDIN
|
||||||
struct ipc_message *m = NULL;
|
struct ipc_message *m = NULL;
|
||||||
m = malloc (sizeof (struct ipc_message));
|
SECURE_BUFFER_HEAP_ALLOCATION_R (m, sizeof (struct ipc_message), , );
|
||||||
memset (m, 0, sizeof (struct ipc_message));
|
|
||||||
|
|
||||||
ret = ipc_write (srv, m);
|
TIPC_P_Q (ipc_message_format_data (m, 42, buf, len), "message format", EXIT_FAILURE);
|
||||||
if (ret != IPC_ERROR_NONE) {
|
|
||||||
handle_err("main", "ipc_write");
|
#if 0
|
||||||
PRINTERR(ret, "ipc_write");
|
printf ("\n");
|
||||||
exit (EXIT_FAILURE);
|
printf ("right before sending a message\n");
|
||||||
}
|
#endif
|
||||||
|
TIPC_P_Q (ipc_write (srv, m), "ipc_write", EXIT_FAILURE);
|
||||||
|
#if 0
|
||||||
|
printf ("right after sending a message\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
ipc_message_empty (m);
|
ipc_message_empty (m);
|
||||||
free (m);
|
free (m);
|
||||||
|
@ -147,7 +114,7 @@ void interactive (char *env[])
|
||||||
case IPC_EVENT_TYPE_MESSAGE:
|
case IPC_EVENT_TYPE_MESSAGE:
|
||||||
{
|
{
|
||||||
struct ipc_message *m = event.m;
|
struct ipc_message *m = event.m;
|
||||||
printf ("msg recv: %.*s", m->length, m->payload);
|
printf ("\rmsg recv: %.*s\n", m->length, m->payload);
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case IPC_EVENT_TYPE_DISCONNECTION:
|
case IPC_EVENT_TYPE_DISCONNECTION:
|
||||||
|
|
|
@ -71,16 +71,20 @@ void main_loop ()
|
||||||
case IPC_EVENT_TYPE_MESSAGE:
|
case IPC_EVENT_TYPE_MESSAGE:
|
||||||
{
|
{
|
||||||
struct ipc_message *m = event.m;
|
struct ipc_message *m = event.m;
|
||||||
if (m->length > 0) {
|
|
||||||
#ifdef PONGD_VERBOSE
|
#ifdef PONGD_VERBOSE
|
||||||
printf ("message received (type %d): %.*s\n", m->type, m->length, m->payload);
|
if (m->length > 0) {
|
||||||
#endif
|
printf ("message received (type %d, user type %d, size %u bytes): %.*s\n", m->type, m->user_type, m->length, m->length, m->payload);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
printf ("message with a 0-byte size :(\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
ret = ipc_write (event.origin, m);
|
ret = ipc_write (event.origin, m);
|
||||||
if (ret != IPC_ERROR_NONE) {
|
if (ret != IPC_ERROR_NONE) {
|
||||||
PRINTERR(ret,"server write");
|
PRINTERR(ret,"server write");
|
||||||
}
|
}
|
||||||
|
printf ("message sent\n");
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case IPC_EVENT_TYPE_ERROR:
|
case IPC_EVENT_TYPE_ERROR:
|
||||||
|
@ -110,7 +114,7 @@ void exit_program(int signal)
|
||||||
printf("Quitting, signal: %d\n", signal);
|
printf("Quitting, signal: %d\n", signal);
|
||||||
|
|
||||||
// free remaining clients
|
// free remaining clients
|
||||||
for (int i = 0; i < clients->size ; i++) {
|
for (size_t i = 0; i < clients->size ; i++) {
|
||||||
struct ipc_connection_info *cli = clients->cinfos[i];
|
struct ipc_connection_info *cli = clients->cinfos[i];
|
||||||
if (cli != NULL) {
|
if (cli != NULL) {
|
||||||
free (cli);
|
free (cli);
|
||||||
|
|
|
@ -23,18 +23,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
int connection(int port)
|
int connection(char *ipstr, int port)
|
||||||
{
|
{
|
||||||
int sockfd;
|
int sockfd;
|
||||||
struct sockaddr_in server;
|
SECURE_DECLARATION (struct sockaddr_in, server);
|
||||||
socklen_t addrlen;
|
socklen_t addrlen;
|
||||||
|
|
||||||
// socket factory
|
// socket factory
|
||||||
if((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
|
T_PERROR_Q (((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1), "socket creation", EXIT_FAILURE);
|
||||||
{
|
|
||||||
perror("socket");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// init remote addr structure and other params
|
// init remote addr structure and other params
|
||||||
server.sin_family = AF_INET;
|
server.sin_family = AF_INET;
|
||||||
|
@ -42,19 +38,11 @@ int connection(int port)
|
||||||
addrlen = sizeof(struct sockaddr_in);
|
addrlen = sizeof(struct sockaddr_in);
|
||||||
|
|
||||||
// get addr from command line and convert it
|
// get addr from command line and convert it
|
||||||
if(inet_pton(AF_INET, "127.0.0.1", &server.sin_addr) <= 0)
|
T_PERROR_Q ((inet_pton(AF_INET, ipstr, &server.sin_addr) <= 0), "inet_pton", EXIT_FAILURE);
|
||||||
{
|
|
||||||
perror("inet_pton");
|
|
||||||
close(sockfd);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Trying to connect to the remote host\n");
|
printf("Trying to connect to the remote host\n");
|
||||||
if(connect(sockfd, (struct sockaddr *) &server, addrlen) == -1)
|
|
||||||
{
|
T_PERROR_Q ((connect(sockfd, (struct sockaddr *) &server, addrlen) == -1), "connection", EXIT_FAILURE);
|
||||||
perror("connect");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Connection OK\n");
|
printf("Connection OK\n");
|
||||||
|
|
||||||
|
@ -63,70 +51,37 @@ int connection(int port)
|
||||||
|
|
||||||
|
|
||||||
void send_receive (int sockfd) {
|
void send_receive (int sockfd) {
|
||||||
unsigned char buf[BUFSIZ];
|
SECURE_BUFFER_DECLARATION (unsigned char, buf, BUFSIZ);
|
||||||
memset (buf, 0, BUFSIZ);
|
int paylen;
|
||||||
|
|
||||||
// first, send service name "pong"
|
// first, send service name "pong"
|
||||||
// send string
|
// send string
|
||||||
if(send(sockfd, "pong", 4, 0) == -1) {
|
T_PERROR_Q ((send(sockfd, "pong", 4, 0) == -1), "sending a message", EXIT_FAILURE);
|
||||||
perror("send pong");
|
|
||||||
close(sockfd);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
printf ("message 'pong' sent\n");
|
printf ("message 'pong' sent\n");
|
||||||
|
|
||||||
|
T_PERROR_Q (((paylen = recv(sockfd, buf, BUFSIZ, 0)) <= 0), "cannot connect to networkd", EXIT_FAILURE);
|
||||||
|
print_hexa ("should be 'OK'", buf, paylen);
|
||||||
memset (buf, 0, BUFSIZ);
|
memset (buf, 0, BUFSIZ);
|
||||||
|
|
||||||
int paylen;
|
|
||||||
paylen = recv(sockfd, buf, BUFSIZ, 0);
|
|
||||||
if (paylen <= 0) {
|
|
||||||
printf ("cannot connect to networkd\n");
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
printf ("should receive 'OK': %*.s\n", paylen, buf);
|
|
||||||
|
|
||||||
memset (buf, 0, BUFSIZ);
|
|
||||||
|
|
||||||
buf[0] = MSG_TYPE_DATA;
|
|
||||||
|
|
||||||
// uint32_t v = htonl(6);
|
|
||||||
// memcpy (buf+1, &v, sizeof (uint32_t));
|
|
||||||
|
|
||||||
uint32_t v = 6;
|
|
||||||
uint32_t net_paylen = htonl (v);
|
|
||||||
memcpy (buf+1, &net_paylen, sizeof (uint32_t));
|
|
||||||
|
|
||||||
buf[5] = 0;
|
|
||||||
memcpy (buf+6, "coucou", 6);
|
|
||||||
|
|
||||||
print_hexa ("SENT MESSAGE", buf, 12);
|
|
||||||
|
|
||||||
// 2 | 6 | 0 | "coucou"
|
// 2 | 6 | 0 | "coucou"
|
||||||
// 1 B | 4 B | 1 | 6 B
|
// 1 B | 4 B | 1 | 6 B
|
||||||
|
ipc_message_raw_serialize ((char *) buf, MSG_TYPE_DATA, 42, "coucou", 6);
|
||||||
if(send(sockfd, buf, 12, 0) == -1) {
|
print_hexa ("WAITING 10 seconds then message to send", buf, 12);
|
||||||
perror("send coucou");
|
// sleep (1);
|
||||||
close(sockfd);
|
T_PERROR_Q ((send(sockfd, buf, 12, 0) == -1), "sending a message", EXIT_FAILURE);
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
printf ("message 'coucou' sent\n");
|
printf ("message 'coucou' sent\n");
|
||||||
|
|
||||||
memset (buf, 0, BUFSIZ);
|
memset (buf, 0, BUFSIZ);
|
||||||
|
|
||||||
paylen = recv (sockfd, buf, BUFSIZ, 0);
|
// receiving a message
|
||||||
if(paylen < 0) {
|
T_PERROR_Q ( ((paylen = recv (sockfd, buf, BUFSIZ, 0)) < 0), "receiving a message", EXIT_FAILURE);
|
||||||
perror("recv a message");
|
|
||||||
close(sockfd);
|
if (paylen == 0) {
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
if (paylen > 0) {
|
|
||||||
print_hexa ("RECEIVED MESSAGE", buf, paylen);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fprintf (stderr, "error: disconnection from the server\n");
|
fprintf (stderr, "error: disconnection from the server\n");
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
print_hexa ("RECEIVED MESSAGE", buf, paylen);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// send string
|
// send string
|
||||||
if(sendto(sockfd, , ), 0) == -1)
|
if(sendto(sockfd, , ), 0) == -1)
|
||||||
|
@ -141,12 +96,17 @@ void send_receive (int sockfd) {
|
||||||
|
|
||||||
int main(int argc, char * argv[])
|
int main(int argc, char * argv[])
|
||||||
{
|
{
|
||||||
|
char *ipstr = "127.0.0.1";
|
||||||
int port = 9000;
|
int port = 9000;
|
||||||
if (argc > 1) {
|
if (argc == 2) {
|
||||||
port = atoi (argv[1]);
|
port = atoi (argv[1]);
|
||||||
}
|
}
|
||||||
|
else if (argc == 3) {
|
||||||
|
ipstr = argv[1];
|
||||||
|
port = atoi (argv[2]);
|
||||||
|
}
|
||||||
|
|
||||||
int sockfd = connection (port);
|
int sockfd = connection (ipstr, port);
|
||||||
|
|
||||||
send_receive (sockfd);
|
send_receive (sockfd);
|
||||||
|
|
||||||
|
|
|
@ -7,12 +7,16 @@
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#define NTAB(t) ((int) (sizeof (t) / sizeof (t)[0]))
|
#define CLOG_DEBUG(a, ...) LOG_DEBUG (""); LOG_DEBUG("\033[36m" a "\033[00m", #__VA_ARGS__); LOG_DEBUG ("")
|
||||||
#define SECURE_BUFFER_DECLARATION(type,name,size) type name[size]; memset(&name, 0, sizeof(type) * size);
|
|
||||||
// print error string
|
void chomp (char *str, size_t len) {
|
||||||
#define PRINT_ERR_STR(code) const char *estr = ipc_errors_get (code); fprintf (stderr, "%s", estr);
|
if (str[len -1] == '\n') {
|
||||||
// Test Print Quit
|
str[len -1] = '\0';
|
||||||
#define T_P_Q(f,err,q) { ret = f; if (ret != IPC_ERROR_NONE) { fprintf (stderr, err); PRINT_ERR_STR(ret); exit (q); } }
|
}
|
||||||
|
if (str[len -2] == '\n') {
|
||||||
|
str[len -2] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
|
@ -30,8 +34,14 @@
|
||||||
if reading on sock_tcp
|
if reading on sock_tcp
|
||||||
sock_client = accept
|
sock_client = accept
|
||||||
ipc_add_fd sock_client
|
ipc_add_fd sock_client
|
||||||
elif reading on sock_client
|
elif
|
||||||
TODO (first draft): print messages
|
if socket bind to another (client to service or service to client)
|
||||||
|
reading on fd ; writing on related fd
|
||||||
|
else
|
||||||
|
connection from the client:
|
||||||
|
1. client sends service name
|
||||||
|
2. networkd establishes a connection to the service
|
||||||
|
3. ack
|
||||||
else
|
else
|
||||||
lolwat shouldn't happen :(
|
lolwat shouldn't happen :(
|
||||||
elif reading on usual socket
|
elif reading on usual socket
|
||||||
|
@ -40,223 +50,89 @@
|
||||||
|
|
||||||
#define SERVICE_NAME "simpletcp"
|
#define SERVICE_NAME "simpletcp"
|
||||||
|
|
||||||
#define PRINTERR(ret,msg) {\
|
|
||||||
const char * err = ipc_errors_get (ret);\
|
|
||||||
fprintf(stderr, "error while %s: %s\n", msg, err);\
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ipc_switching {
|
|
||||||
int orig;
|
|
||||||
int dest;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ipc_switchings {
|
|
||||||
struct ipc_switching *collection;
|
|
||||||
size_t size;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct networkd {
|
|
||||||
int cpt;
|
|
||||||
struct ipc_connection_info *srv;
|
|
||||||
struct ipc_connection_infos *clients;
|
|
||||||
struct ipc_switchings * TCP_TO_IPC;
|
|
||||||
struct ipc_switchings * IPC_TO_TCP;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct networkd * ctx;
|
struct networkd * ctx;
|
||||||
|
|
||||||
|
void handle_disconnection (int fd)
|
||||||
void ipc_switching_add (struct ipc_switchings *is, int orig, int dest)
|
|
||||||
{
|
{
|
||||||
is->collection = realloc(is->collection, sizeof(struct ipc_switching) * (is->size+1));
|
// disconnection
|
||||||
if (is->collection == NULL) {
|
LOG_DEBUG ("CLOSE CONNECTION %d", fd);
|
||||||
printf ("error realloc\n");
|
|
||||||
exit (EXIT_FAILURE);
|
int delfd;
|
||||||
|
|
||||||
|
delfd = ipc_switching_del (ctx->TCP_TO_IPC, fd);
|
||||||
|
if (delfd >= 0) {
|
||||||
|
LOG_DEBUG ("CLOSE RELATED CONNECTION %d", delfd);
|
||||||
|
close (delfd);
|
||||||
|
ipc_del_fd (ctx->clients, delfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
is->size++;
|
close (fd);
|
||||||
|
ipc_del_fd (ctx->clients, fd);
|
||||||
|
|
||||||
is->collection[is->size-1].orig = orig;
|
printf ("\n\n");
|
||||||
is->collection[is->size-1].dest = dest;
|
// printf ("TCP_TO_IPC\n");
|
||||||
|
ipc_switching_print (ctx->TCP_TO_IPC);
|
||||||
|
|
||||||
|
printf ("\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int ipc_switching_del (struct ipc_switchings *is, int orig)
|
void tcp_connection (char **env, int fd)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < is->size; i++) {
|
SECURE_BUFFER_DECLARATION(char, buf, BUFSIZ);
|
||||||
if (is->collection[i].orig == orig) {
|
|
||||||
is->collection[i].orig = is->collection[is->size-1].orig;
|
|
||||||
int ret = is->collection[i].dest;
|
|
||||||
is->collection[i].dest = is->collection[is->size-1].dest;
|
|
||||||
|
|
||||||
size_t s = (is->size - 1) > 0 ? (is->size - 1) : 1;
|
ssize_t len = recv (fd, buf, BUFSIZ, 0);
|
||||||
|
if (len <= 0) {
|
||||||
is->collection = realloc(is->collection, sizeof(struct ipc_switching) * s);
|
handle_disconnection (fd);
|
||||||
if (is->collection == NULL) {
|
return ;
|
||||||
printf ("error realloc\n");
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
is->size--;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ipc_switching_get (struct ipc_switchings *is, int orig) {
|
|
||||||
for (size_t i = 0; i < is->size; i++) {
|
|
||||||
if (is->collection[i].orig == orig) {
|
|
||||||
return is->collection[i].dest;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ipc_switching_print (struct ipc_switchings *is) {
|
|
||||||
printf ("print!\n");
|
|
||||||
for (size_t i = 0; i < is->size; i++)
|
|
||||||
{
|
|
||||||
printf ("client %d - %d\n", is->collection[i].orig, is->collection[i].dest);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void tcp_connection (char **env, int fd, char * buf, int len)
|
|
||||||
{
|
|
||||||
printf ("tcp client %d is not already connected to a service\n", fd);
|
|
||||||
buf[len] = '\0';
|
buf[len] = '\0';
|
||||||
|
|
||||||
// for testing purposes
|
// XXX: for testing purposes
|
||||||
size_t last_char = strlen ((const char*)buf) -1;
|
chomp (buf, len);
|
||||||
if (buf[last_char] == '\n') {
|
LOG_DEBUG ("SHOULD CONNECT TO %s", buf);
|
||||||
buf[last_char] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
printf ("read something: where to connect %s\n", buf);
|
|
||||||
printf ("sending ok\n");
|
|
||||||
|
|
||||||
// TODO: tests
|
// TODO: tests
|
||||||
if (send (fd, "OK", 2, 0) <= 0) {
|
T_PERROR_Q ( (send (fd, "OK", 2, 0) <= 0), "sending a message", EXIT_FAILURE);
|
||||||
fprintf (stderr, "error: cannot send message\n");
|
|
||||||
perror("send");
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
SECURE_DECLARATION (struct ipc_connection_info, tcp_to_ipc_ci);
|
SECURE_DECLARATION (struct ipc_connection_info, tcp_to_ipc_ci);
|
||||||
|
|
||||||
enum ipc_errors ret = 0;
|
TIPC_F_Q (ipc_connection (env, &tcp_to_ipc_ci, buf), ("cannot connect to the service [%s]", buf), EXIT_FAILURE);
|
||||||
T_P_Q (ipc_connection (env, &tcp_to_ipc_ci, buf), "cannot connect to the service\n", EXIT_FAILURE);
|
|
||||||
|
|
||||||
ipc_switching_add (ctx->TCP_TO_IPC, fd, tcp_to_ipc_ci.fd);
|
ipc_switching_add (ctx->TCP_TO_IPC, fd, tcp_to_ipc_ci.fd);
|
||||||
ipc_switching_add (ctx->IPC_TO_TCP, tcp_to_ipc_ci.fd, fd);
|
|
||||||
ipc_add_fd (ctx->clients, tcp_to_ipc_ci.fd);
|
ipc_add_fd (ctx->clients, tcp_to_ipc_ci.fd);
|
||||||
|
|
||||||
|
LOG_DEBUG ("CONNECTION TO SERVICE client %d -> %d", fd, tcp_to_ipc_ci.fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_extra_socket (struct ipc_event event, int sockfd, char **env)
|
int accept_new_client (int serverfd)
|
||||||
{
|
{
|
||||||
SECURE_DECLARATION (struct sockaddr_in, client);
|
SECURE_DECLARATION (struct sockaddr_in, client);
|
||||||
socklen_t addrlen = 0;
|
socklen_t addrlen = 0;
|
||||||
|
|
||||||
printf ("something comes from somewhere: fd %d\n", event.origin->fd);
|
|
||||||
|
|
||||||
// NEW CLIENT
|
|
||||||
if (event.origin->fd == sockfd) {
|
|
||||||
int sock_fd_client;
|
int sock_fd_client;
|
||||||
if((sock_fd_client = accept(sockfd, (struct sockaddr *) &client, &addrlen)) == -1) {
|
T_PERROR_Q (((sock_fd_client = accept(serverfd, (struct sockaddr *) &client, &addrlen)) == -1), "accept new client", EXIT_FAILURE);
|
||||||
perror("accept");
|
|
||||||
close(sockfd);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
printf ("after accept\n");
|
|
||||||
// adding a client
|
// adding a client
|
||||||
ipc_add_fd (ctx->clients, sock_fd_client);
|
ipc_add_fd (ctx->clients, sock_fd_client);
|
||||||
printf ("after ipc_add_fd, TCP client: %d\n", sock_fd_client);
|
|
||||||
}
|
|
||||||
// CLIENT IS TALKING
|
|
||||||
else {
|
|
||||||
SECURE_BUFFER_DECLARATION(char, buf, 4096);
|
|
||||||
|
|
||||||
ssize_t len = recv (event.origin->fd, buf, 4096, 0);
|
return sock_fd_client;
|
||||||
if (len > 0) {
|
|
||||||
|
|
||||||
print_hexa ("RECEIVED", (unsigned char*) buf, len);
|
|
||||||
|
|
||||||
// TODO: check if the message comes from an external IPC
|
|
||||||
int fd = ipc_switching_get (ctx->IPC_TO_TCP, event.origin->fd);
|
|
||||||
|
|
||||||
if (fd >= 0) {
|
|
||||||
printf ("SWITCH: ipc service %d sent a message for %d\n", event.origin->fd, fd);
|
|
||||||
int sent_len = send (fd, buf, len, 0);
|
|
||||||
if (sent_len < 0) {
|
|
||||||
perror ("write to ipc");
|
|
||||||
}
|
}
|
||||||
else if (sent_len != len) {
|
|
||||||
fprintf (stderr, "write NOT ENOUGH to tcp client\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fd = ipc_switching_get (ctx->TCP_TO_IPC, event.origin->fd);
|
|
||||||
if (fd >= 0) {
|
|
||||||
printf ("SWITCH: client %d sent a message for %d\n", event.origin->fd, fd);
|
|
||||||
int sent_len = send (fd, buf, len, 0);
|
|
||||||
if (sent_len < 0) {
|
|
||||||
perror ("write to ipc");
|
|
||||||
}
|
|
||||||
else if (sent_len != len) {
|
|
||||||
fprintf (stderr, "write NOT ENOUGH to ipc\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
tcp_connection (env, event.origin->fd, buf, len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (len == 0) {
|
|
||||||
// disconnection
|
|
||||||
printf ("close connection\n");
|
|
||||||
|
|
||||||
int delfd = ipc_switching_del (ctx->TCP_TO_IPC, event.origin->fd);
|
|
||||||
if (delfd >= 0) {
|
|
||||||
close (delfd);
|
|
||||||
ipc_del_fd (ctx->clients, delfd);
|
|
||||||
}
|
|
||||||
|
|
||||||
delfd = ipc_switching_del (ctx->IPC_TO_TCP, event.origin->fd);
|
|
||||||
if (delfd >= 0) {
|
|
||||||
close (delfd);
|
|
||||||
ipc_del_fd (ctx->clients, delfd);
|
|
||||||
}
|
|
||||||
|
|
||||||
close (event.origin->fd);
|
|
||||||
ipc_del_fd (ctx->clients, event.origin->fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void main_loop (int argc, char **argv, char **env)
|
void main_loop (int argc, char **argv, char **env)
|
||||||
{
|
{
|
||||||
argc = argc; // FIXME: useless
|
argc = argc; // FIXME: useless
|
||||||
int sockfd;
|
int serverfd;
|
||||||
|
|
||||||
struct sockaddr_in my_addr;
|
SECURE_DECLARATION (struct sockaddr_in, my_addr);
|
||||||
socklen_t addrlen;
|
socklen_t addrlen;
|
||||||
|
|
||||||
// socket factory
|
// socket factory
|
||||||
if((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
|
T_PERROR_R (((serverfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1), "socket", );
|
||||||
{
|
|
||||||
perror("socket");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
int yes = 1;
|
int yes = 1;
|
||||||
|
|
||||||
if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
|
T_PERROR_R ((setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1), "setsockopt", );
|
||||||
perror ("setsockopt");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// init local addr structure and other params
|
// init local addr structure and other params
|
||||||
my_addr.sin_family = AF_INET;
|
my_addr.sin_family = AF_INET;
|
||||||
|
@ -265,57 +141,51 @@ void main_loop (int argc, char **argv, char **env)
|
||||||
addrlen = sizeof(struct sockaddr_in);
|
addrlen = sizeof(struct sockaddr_in);
|
||||||
|
|
||||||
// bind addr structure with socket
|
// bind addr structure with socket
|
||||||
if(bind(sockfd, (struct sockaddr *) &my_addr, addrlen) == -1)
|
T_PERROR_R ((bind(serverfd, (struct sockaddr *) &my_addr, addrlen) == -1), "bind", );
|
||||||
{
|
|
||||||
perror("bind");
|
|
||||||
close(sockfd);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the socket in passive mode (only used for accept())
|
// set the socket in passive mode (only used for accept())
|
||||||
// and set the list size for pending connection
|
// and set the list size for pending connection
|
||||||
if(listen(sockfd, 5) == -1)
|
T_PERROR_R ((listen(serverfd, 5) == -1), "listen", );
|
||||||
{
|
|
||||||
perror("listen");
|
|
||||||
close(sockfd);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Waiting for incomming connection\n");
|
printf("Waiting for incomming connection\n");
|
||||||
|
|
||||||
|
SECURE_BUFFER_HEAP_ALLOCATION_Q (ctx->clients, sizeof (struct ipc_connection_infos), , EXIT_FAILURE);
|
||||||
|
SECURE_DECLARATION (struct ipc_event, event);
|
||||||
|
|
||||||
enum ipc_errors ret = 0;
|
printf ("adding serverfd to ctx->clients\n");
|
||||||
|
ipc_add_fd (ctx->clients, serverfd);
|
||||||
ctx->clients = malloc (sizeof (struct ipc_connection_infos));
|
|
||||||
memset(ctx->clients, 0, sizeof(struct ipc_connection_infos));
|
|
||||||
|
|
||||||
struct ipc_event event;
|
|
||||||
memset(&event, 0, sizeof (struct ipc_event));
|
|
||||||
printf ("adding sockfd to ctx->clients\n");
|
|
||||||
ipc_add_fd (ctx->clients, sockfd);
|
|
||||||
|
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
// ipc_service_poll_event provides one event at a time
|
// ipc_wait_event provides one event at a time
|
||||||
// warning: event->m is free'ed if not NULL
|
// warning: event->m is free'ed if not NULL
|
||||||
// printf ("before wait event\n"); // TODO remove
|
TIPC_T_P_I_R (
|
||||||
ret = ipc_wait_event (ctx->clients, ctx->srv, &event);
|
/* function to test */ ipc_wait_event_networkd (ctx->clients, ctx->srv, &event, ctx->TCP_TO_IPC)
|
||||||
// printf ("after wait event\n"); // TODO remove
|
, /* error condition */ ret != IPC_ERROR_NONE && ret != IPC_ERROR_CLOSED_RECIPIENT
|
||||||
if (ret != IPC_ERROR_NONE && ret != IPC_ERROR_CLOSED_RECIPIENT) {
|
, /* to say on error */ "wait event"
|
||||||
PRINTERR(ret,"wait event");
|
, /* to do on error */ LOG_ERROR ("\033[31m error happened\033[00m"); TIPC_P (ipc_server_close (ctx->srv), "server close")
|
||||||
|
, /* return function */ return );
|
||||||
// the application will shut down, and close the service
|
|
||||||
ret = ipc_server_close (ctx->srv);
|
|
||||||
if (ret != IPC_ERROR_NONE) {
|
|
||||||
PRINTERR(ret,"server close");
|
|
||||||
}
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
|
case IPC_EVENT_TYPE_SWITCH:
|
||||||
|
{
|
||||||
|
printf ("switch happened\n");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case IPC_EVENT_TYPE_EXTRA_SOCKET:
|
case IPC_EVENT_TYPE_EXTRA_SOCKET:
|
||||||
{
|
{
|
||||||
handle_extra_socket (event, sockfd, env);
|
// NEW CLIENT
|
||||||
|
if (event.origin->fd == serverfd) {
|
||||||
|
int sock_fd_client = accept_new_client (serverfd);
|
||||||
|
ctx->cpt++;
|
||||||
|
printf ("TCP connection: %d clients connected\n", ctx->cpt);
|
||||||
|
printf ("new TCP client has the fd %d\n", sock_fd_client);
|
||||||
|
}
|
||||||
|
// CLIENT IS TALKING
|
||||||
|
else {
|
||||||
|
tcp_connection (env, event.origin->fd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -326,13 +196,15 @@ void main_loop (int argc, char **argv, char **env)
|
||||||
printf ("new client has the fd %d\n", (event.origin)->fd);
|
printf ("new client has the fd %d\n", (event.origin)->fd);
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IPC_EVENT_TYPE_DISCONNECTION:
|
case IPC_EVENT_TYPE_DISCONNECTION:
|
||||||
{
|
{
|
||||||
ctx->cpt--;
|
ctx->cpt--;
|
||||||
printf ("disconnection: %d clients remaining\n", ctx->cpt);
|
printf ("disconnection: %d clients remaining\n", ctx->cpt);
|
||||||
|
|
||||||
// free the ipc_client structure
|
// free the ipc_client structure
|
||||||
free (event.origin);
|
// if (event.origin != NULL)
|
||||||
|
// free (event.origin);
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case IPC_EVENT_TYPE_MESSAGE:
|
case IPC_EVENT_TYPE_MESSAGE:
|
||||||
|
@ -342,24 +214,14 @@ void main_loop (int argc, char **argv, char **env)
|
||||||
printf ("message received (type %d): %.*s\n", m->type, m->length, m->payload);
|
printf ("message received (type %d): %.*s\n", m->type, m->length, m->payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ipc_write (event.origin, m);
|
TIPC_P (ipc_write (event.origin, m), "server write");
|
||||||
|
|
||||||
if (ret != IPC_ERROR_NONE) {
|
|
||||||
handle_err( "handle_new_msg", "server_write < 0");
|
|
||||||
PRINTERR(ret,"server write");
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case IPC_EVENT_TYPE_ERROR:
|
case IPC_EVENT_TYPE_ERROR:
|
||||||
{
|
fprintf (stderr, "a problem happened with client %d\n", (event.origin)->fd);
|
||||||
fprintf (stderr, "a problem happened with client %d\n"
|
|
||||||
, (event.origin)->fd);
|
|
||||||
};
|
|
||||||
break;
|
break;
|
||||||
default :
|
default :
|
||||||
{
|
|
||||||
fprintf (stderr, "there must be a problem, event not set\n");
|
fprintf (stderr, "there must be a problem, event not set\n");
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,7 +235,7 @@ void exit_program(int signal)
|
||||||
printf("Quitting, signal: %d\n", signal);
|
printf("Quitting, signal: %d\n", signal);
|
||||||
|
|
||||||
// free remaining clients
|
// free remaining clients
|
||||||
for (int i = 0; i < ctx->clients->size ; i++) {
|
for (size_t i = 0; i < ctx->clients->size ; i++) {
|
||||||
struct ipc_connection_info *cli = ctx->clients->cinfos[i];
|
struct ipc_connection_info *cli = ctx->clients->cinfos[i];
|
||||||
if (cli != NULL) {
|
if (cli != NULL) {
|
||||||
free (cli);
|
free (cli);
|
||||||
|
@ -382,20 +244,15 @@ void exit_program(int signal)
|
||||||
}
|
}
|
||||||
|
|
||||||
ipc_connections_free (ctx->clients);
|
ipc_connections_free (ctx->clients);
|
||||||
free (ctx->clients);
|
|
||||||
|
|
||||||
|
|
||||||
// the application will shut down, and close the service
|
// the application will shut down, and close the service
|
||||||
enum ipc_errors ret = ipc_server_close (ctx->srv);
|
TIPC_P (ipc_server_close (ctx->srv), "server close");
|
||||||
if (ret != IPC_ERROR_NONE) {
|
|
||||||
PRINTERR(ret,"server close");
|
|
||||||
}
|
|
||||||
free (ctx->srv);
|
|
||||||
|
|
||||||
|
// free, free everything!
|
||||||
|
free (ctx->clients);
|
||||||
|
free (ctx->srv);
|
||||||
free (ctx->TCP_TO_IPC->collection);
|
free (ctx->TCP_TO_IPC->collection);
|
||||||
free (ctx->TCP_TO_IPC);
|
free (ctx->TCP_TO_IPC);
|
||||||
free (ctx->IPC_TO_TCP->collection);
|
|
||||||
free (ctx->IPC_TO_TCP);
|
|
||||||
free (ctx);
|
free (ctx);
|
||||||
|
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
|
@ -412,39 +269,18 @@ int main(int argc, char * argv[], char **env)
|
||||||
if(argc != 2)
|
if(argc != 2)
|
||||||
{
|
{
|
||||||
printf("USAGE: %s port_num\n", argv[0]);
|
printf("USAGE: %s port_num\n", argv[0]);
|
||||||
exit(-1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("pid = %d\n", getpid ());
|
printf ("pid = %d\n", getpid ());
|
||||||
|
|
||||||
ctx = malloc (sizeof (struct networkd));
|
SECURE_BUFFER_HEAP_ALLOCATION_Q (ctx, sizeof (struct networkd), , EXIT_FAILURE);
|
||||||
memset (ctx, 0, sizeof (struct networkd));
|
SECURE_BUFFER_HEAP_ALLOCATION_Q (ctx->TCP_TO_IPC, sizeof(struct ipc_switchings), , EXIT_FAILURE);
|
||||||
|
SECURE_BUFFER_HEAP_ALLOCATION_Q (ctx->TCP_TO_IPC->collection, sizeof(struct ipc_switching), , EXIT_FAILURE);
|
||||||
|
SECURE_BUFFER_HEAP_ALLOCATION_Q (ctx->srv, sizeof (struct ipc_connection_info), , EXIT_FAILURE);
|
||||||
|
|
||||||
|
TIPC_P_R (ipc_server_init (env, ctx->srv, SERVICE_NAME), "server init", EXIT_FAILURE);
|
||||||
ctx->TCP_TO_IPC = malloc(sizeof(struct ipc_switchings));
|
printf ("Listening on [%s].\n", ctx->srv->spath);
|
||||||
memset (ctx->TCP_TO_IPC, 0, sizeof(struct ipc_switchings));
|
|
||||||
ctx->TCP_TO_IPC->collection = malloc(sizeof(struct ipc_switching));
|
|
||||||
ctx->IPC_TO_TCP = malloc(sizeof(struct ipc_switchings));
|
|
||||||
memset (ctx->IPC_TO_TCP, 0, sizeof(struct ipc_switchings));
|
|
||||||
ctx->IPC_TO_TCP->collection = malloc(sizeof(struct ipc_switching));
|
|
||||||
|
|
||||||
ctx->srv = malloc (sizeof (struct ipc_connection_info));
|
|
||||||
if (ctx->srv == NULL) {
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
memset (ctx->srv, 0, sizeof (struct ipc_connection_info));
|
|
||||||
ctx->srv->type = '\0';
|
|
||||||
ctx->srv->index = 0;
|
|
||||||
ctx->srv->version = 0;
|
|
||||||
ctx->srv->fd = 0;
|
|
||||||
ctx->srv->spath = NULL;
|
|
||||||
|
|
||||||
enum ipc_errors ret = ipc_server_init (env, ctx->srv, SERVICE_NAME);
|
|
||||||
if (ret != IPC_ERROR_NONE) {
|
|
||||||
PRINTERR(ret,"server init");
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
printf ("Listening on %s.\n", ctx->srv->spath);
|
|
||||||
|
|
||||||
printf("MAIN: server created\n" );
|
printf("MAIN: server created\n" );
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "../src/ipc.h"
|
||||||
|
|
||||||
|
#define DEFAULT_IPC_NETWORK "IPC_NETWORK=\"pong local:lolwat\""
|
||||||
|
|
||||||
|
int main(int argc, char * argv[])
|
||||||
|
{
|
||||||
|
|
||||||
|
(void) argc;
|
||||||
|
(void) argv;
|
||||||
|
|
||||||
|
enum ipc_errors ret;
|
||||||
|
SECURE_DECLARATION (struct ipc_connection_info, srv);
|
||||||
|
|
||||||
|
if (argc != 2) {
|
||||||
|
fprintf (stderr, "usage: %s service_name\n", argv[0]);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *service_name = argv[1];
|
||||||
|
|
||||||
|
// ask for a local service "pong"
|
||||||
|
// inform the network service that it's now named "lolwat"
|
||||||
|
char *ipc_network = getenv("IPC_NETWORK");
|
||||||
|
if (ipc_network == NULL) {
|
||||||
|
ipc_network = DEFAULT_IPC_NETWORK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ipc_contact_networkd (&srv, service_name, ipc_network);
|
||||||
|
|
||||||
|
printf ("ret = %d\n", ret);
|
||||||
|
|
||||||
|
if (ret == 0 && srv.fd != 0) {
|
||||||
|
printf ("Success\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf ("Ow. :(\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
usock_close (srv.fd);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "../src/ipc.h"
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char * argv[], char *env[])
|
||||||
|
{
|
||||||
|
|
||||||
|
(void) argc;
|
||||||
|
(void) argv;
|
||||||
|
|
||||||
|
enum ipc_errors ret;
|
||||||
|
SECURE_DECLARATION (struct ipc_connection_info, srv);
|
||||||
|
SECURE_DECLARATION (struct ipc_connection_info, client);
|
||||||
|
SECURE_DECLARATION (struct ipc_connection_info, contacted_service);
|
||||||
|
|
||||||
|
|
||||||
|
// service start
|
||||||
|
TIPC_P_RR (ipc_server_init (env, &srv, "network"), "Networkd cannot be initialized");
|
||||||
|
|
||||||
|
printf ("service initialized, waiting for a client\n");
|
||||||
|
|
||||||
|
// accept a new client
|
||||||
|
TIPC_P_RR (ipc_accept (&srv, &client), "cannot accept the client during handle_new_connection");
|
||||||
|
|
||||||
|
// TODO: read a message to know the requested service
|
||||||
|
SECURE_DECLARATION (struct ipc_message, msg);
|
||||||
|
ret = ipc_read (&client, &msg);
|
||||||
|
printf ("received message: %s\n", msg.payload);
|
||||||
|
|
||||||
|
/** TODO: contact the service */
|
||||||
|
printf ("WARNING: currently this program only ask for pong service %d\n", ret);
|
||||||
|
TIPC_P_RR (ipc_connection (env, &contacted_service, "pong"), "cannot connect to the requested service");
|
||||||
|
|
||||||
|
ipc_provide_fd (client.fd, contacted_service.fd);
|
||||||
|
|
||||||
|
TIPC_P_RR (ipc_server_close (&srv), "Networkd cannot be stopped!!");
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "../src/ipc.h"
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
SECURE_BUFFER_DECLARATION (char, buffer, BUFSIZ);
|
||||||
|
|
||||||
|
log_get_logfile_name (buffer, BUFSIZ);
|
||||||
|
|
||||||
|
printf ("log: %s\n", buffer);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
|
@ -0,0 +1,118 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#include "../src/ipc.h"
|
||||||
|
#include "../src/utils.h"
|
||||||
|
|
||||||
|
#define WEBSOCKETD_BULLSHIT
|
||||||
|
|
||||||
|
void chomp (char *str, ssize_t len) {
|
||||||
|
if (str[len -1] == '\n') {
|
||||||
|
str[len -1] = '\0';
|
||||||
|
}
|
||||||
|
if (str[len -2] == '\n') {
|
||||||
|
str[len -2] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ipc_connection_info *srv;
|
||||||
|
|
||||||
|
void interactive (char *env[])
|
||||||
|
{
|
||||||
|
SECURE_BUFFER_DECLARATION (char, service_name, 100);
|
||||||
|
|
||||||
|
char *sn = getenv("PATH_TRANSLATED");
|
||||||
|
|
||||||
|
if (sn != NULL) {
|
||||||
|
memcpy (service_name, sn, strlen(sn));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf (stderr, "cannot see PATH_TRANSLATED variable\n");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// init service
|
||||||
|
TIPC_P_Q (ipc_connection (env, srv, service_name), "application connection", EXIT_FAILURE);
|
||||||
|
|
||||||
|
SECURE_DECLARATION (struct ipc_event, event);
|
||||||
|
SECURE_DECLARATION (struct ipc_connection_infos, services);
|
||||||
|
|
||||||
|
ipc_add (&services, srv);
|
||||||
|
ipc_add_fd (&services, 0); // add STDIN
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
TIPC_P_Q (ipc_wait_event (&services, NULL, &event), "wait event", EXIT_FAILURE);
|
||||||
|
|
||||||
|
switch (event.type) {
|
||||||
|
case IPC_EVENT_TYPE_EXTRA_SOCKET:
|
||||||
|
{
|
||||||
|
// structure not read, should read the message here
|
||||||
|
SECURE_BUFFER_DECLARATION (char, buf, 4096);
|
||||||
|
ssize_t len;
|
||||||
|
|
||||||
|
len = read (event.origin->fd, buf, 4096);
|
||||||
|
|
||||||
|
// in case we want to quit the program
|
||||||
|
if ( len == 0
|
||||||
|
|| strncmp (buf, "quit", 4) == 0
|
||||||
|
|| strncmp (buf, "exit", 4) == 0) {
|
||||||
|
|
||||||
|
TIPC_P_Q (ipc_close (srv), "application close", EXIT_FAILURE);
|
||||||
|
|
||||||
|
ipc_connections_free (&services);
|
||||||
|
|
||||||
|
exit (EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// send the message read on STDIN
|
||||||
|
ssize_t len_sent = write (srv->fd, buf, len);
|
||||||
|
if (len_sent != len) {
|
||||||
|
fprintf (stderr, "cannot send the message %lu-byte message, sent %lu bytes"
|
||||||
|
, len, len_sent);
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IPC_EVENT_TYPE_MESSAGE:
|
||||||
|
{
|
||||||
|
struct ipc_message *m = event.m;
|
||||||
|
SECURE_BUFFER_DECLARATION (char, buf, 4096);
|
||||||
|
uint32_t size;
|
||||||
|
size = ipc_message_raw_serialize (buf, m->type, m->user_type, m->payload, m->length);
|
||||||
|
|
||||||
|
write (1, buf, size);
|
||||||
|
#ifdef WEBSOCKETD_BULLSHIT
|
||||||
|
printf ("\n");
|
||||||
|
#endif
|
||||||
|
fflush (stdout);
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
ERROR_CASE (IPC_EVENT_TYPE_DISCONNECTION, "main loop", "disconnection: should not happen");
|
||||||
|
ERROR_CASE (IPC_EVENT_TYPE_NOT_SET , "main loop", "not set: should not happen");
|
||||||
|
ERROR_CASE (IPC_EVENT_TYPE_CONNECTION , "main loop", "connection: should not happen");
|
||||||
|
// ERROR_CASE (IPC_EVENT_TYPE_ERROR , "main loop", "error");
|
||||||
|
default :
|
||||||
|
fprintf (stderr, "event type error: should not happen, event type %d\n", event.type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (int argc, char *argv[], char *env[])
|
||||||
|
{
|
||||||
|
argc = argc; // warnings
|
||||||
|
argv = argv; // warnings
|
||||||
|
|
||||||
|
srv = malloc (sizeof (struct ipc_connection_info));
|
||||||
|
memset (srv, 0, sizeof (struct ipc_connection_info));
|
||||||
|
|
||||||
|
// index and version should be filled
|
||||||
|
srv->index = 0;
|
||||||
|
srv->version = 0;
|
||||||
|
|
||||||
|
interactive (env);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
Reference in New Issue