Archived
3
0

tcpd adapted for unix socket

This commit is contained in:
lapupe 2016-10-28 13:58:04 +02:00
parent f4ba61f02d
commit b2abfb970e
10 changed files with 403 additions and 255 deletions

View File

@ -3,6 +3,11 @@
#include <time.h> #include <time.h>
#include <errno.h> #include <errno.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h>
#define LISTEN_BACKLOG 50
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)
int file_write (const int fd, const char *buf, const int msize) int file_write (const int fd, const char *buf, const int msize)
{ {
@ -147,7 +152,7 @@ int srv_close (struct service *srv)
return 0; return 0;
} }
int srv_get_new_process (const char *buf, struct process *p) int srv_get_new_process (char *buf, struct process *p)
{ {
/*char *buf = malloc(BUFSIZ); /*char *buf = malloc(BUFSIZ);
memset(buf, 0, BUFSIZ); memset(buf, 0, BUFSIZ);
@ -192,18 +197,19 @@ int srv_get_new_process (const char *buf, struct process *p)
return 0; return 0;
} }
int srv_read (struct process *p, char ** buf) int srv_read (const struct service *srv, char ** buf)
{ {
return file_read (p->proc_fd, buf); return file_read (srv->service_fd, buf);
} }
int srv_write (struct process *p, char * buf, size_t msize) int srv_write (const struct service *srv, const char * buf, size_t msize)
{ {
return file_write (p->proc_fd, buf, msize); return file_write (srv->service_fd, buf, msize);
} }
// APPLICATION // APPLICATION
//Init connection with unix socket
// send the connection string to $TMP/<service> // send the connection string to $TMP/<service>
int app_srv_connection (struct service *srv, const char *connectionstr, size_t msize) int app_srv_connection (struct service *srv, const char *connectionstr, size_t msize)
{ {
@ -211,7 +217,53 @@ int app_srv_connection (struct service *srv, const char *connectionstr, size_t m
return -1; return -1;
} }
return file_write (srv->server_fd, connectionstr, msize); int sfd;
struct sockaddr_un my_addr;
socklen_t peer_addr_size;
sfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sfd == -1)
return -1;
memset(&my_addr, 0, sizeof(struct sockaddr_un));
// Clear structure
my_addr.sun_family = AF_UNIX;
strncpy(my_addr.sun_path, srv->spath, sizeof(my_addr.sun_path) - 1);
peer_addr_size = sizeof(struct sockaddr_un);
if(connect(sfd,(struct sockaddr *) &my_addr, peer_addr_size) == -1)
{
perror("connect()");
exit(errno);
}
srv->service_fd = sfd;
return srv_write(srv, connectionstr, msize);
}
int proc_connection(struct process *p) {
int sfd;
struct sockaddr_un my_addr;
socklen_t peer_addr_size;
sfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sfd == -1)
return -1;
memset(&my_addr, 0, sizeof(struct sockaddr_un));
// Clear structure
my_addr.sun_family = AF_UNIX;
strncpy(my_addr.sun_path, p->path_proc, sizeof(my_addr.sun_path) - 1);
peer_addr_size = sizeof(struct sockaddr_un);
if(connect(sfd,(struct sockaddr *) &my_addr, peer_addr_size) == -1)
{
perror("connect()");
exit(errno);
}
p->proc_fd = sfd;
return 0;
} }
int app_create (struct process *p, pid_t pid, int index, int version) int app_create (struct process *p, pid_t pid, int index, int version)
@ -342,3 +394,29 @@ int app_write (struct process *p, char * buf, size_t msize)
{ {
return file_write (p->proc_fd, buf, msize); return file_write (p->proc_fd, buf, msize);
} }
/*init a unix socket : bind, listen
*and return a socket
*/
int set_listen_socket(const char *path) {
int sfd;
struct sockaddr_un my_addr;
sfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sfd == -1)
return -1;
memset(&my_addr, 0, sizeof(struct sockaddr_un));
/* Clear structure */
my_addr.sun_family = AF_UNIX;
strncpy(my_addr.sun_path, path, sizeof(my_addr.sun_path) - 1);
unlink(my_addr.sun_path);
if (bind(sfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr_un)) == -1)
return -1;
if (listen(sfd, LISTEN_BACKLOG) == -1)
return -1;
return sfd;
}

View File

@ -30,7 +30,7 @@ struct service {
unsigned int version; unsigned int version;
unsigned int index; unsigned int index;
char spath[PATH_MAX]; char spath[PATH_MAX];
int server_fd; int service_fd;
}; };
int srv_init (int argc, char **argv, char **env int srv_init (int argc, char **argv, char **env
@ -38,7 +38,7 @@ int srv_init (int argc, char **argv, char **env
, int (*cb)(int argc, char **argv, char **env , int (*cb)(int argc, char **argv, char **env
, struct service *srv, const char *sname)); , struct service *srv, const char *sname));
int srv_get_new_process (const char *buf, struct process *proc); int srv_get_new_process (char *buf, struct process *proc);
/* /*
* returns * returns
@ -50,8 +50,8 @@ int srv_get_new_process (const char *buf, struct process *proc);
int srv_create (struct service *srv); int srv_create (struct service *srv);
int srv_close (struct service *srv); int srv_close (struct service *srv);
int srv_read (struct process *, char ** buf); int srv_read (const struct service *, char ** buf);
int srv_write (struct process *, char * buf, size_t); int srv_write (const struct service *, const char * buf, size_t);
// APPLICATION // APPLICATION
@ -71,6 +71,12 @@ int file_write (int fd, const char *buf, const int m_size);
//close socket //close socket
int close_socket(int fd); int close_socket(int fd);
//set and return a listen socket
int set_listen_socket(const char *path);
//init a proc connection
int proc_connection(struct process *p);
//open, close, read, write //open, close, read, write
#endif #endif

View File

@ -4,38 +4,10 @@
#include <sys/un.h> #include <sys/un.h>
#define PONGD_SERVICE_NAME "pongd" #define PONGD_SERVICE_NAME "pongd"
#define LISTEN_BACKLOG 50
#define handle_error(msg) \ #define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0) do { perror(msg); exit(EXIT_FAILURE); } while (0)
/*init a unit socket : bind, listen
*and return a socket
*/
int set_listen_socket(const char *path) {
int sfd;
struct sockaddr_un my_addr;
sfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sfd == -1)
return -1;
memset(&my_addr, 0, sizeof(struct sockaddr_un));
/* Clear structure */
my_addr.sun_family = AF_UNIX;
strncpy(my_addr.sun_path, path, sizeof(my_addr.sun_path) - 1);
unlink(my_addr.sun_path);
if (bind(sfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr_un)) == -1)
return -1;
if (listen(sfd, LISTEN_BACKLOG) == -1)
return -1;
return sfd;
}
/* control the file descriptor*/ /* control the file descriptor*/
void * pongd_thread(void * pdata) { void * pongd_thread(void * pdata) {
struct process *proc = (struct process*) pdata; struct process *proc = (struct process*) pdata;
@ -54,44 +26,37 @@ void * pongd_thread(void * pdata) {
struct sockaddr_un peer_addr; struct sockaddr_un peer_addr;
socklen_t peer_addr_size; socklen_t peer_addr_size;
printf("%s\n", proc->path_proc); printf("%s\n", proc->path_proc);
//app_create(proc, proc->pid, proc->index, proc->version);
sfd = set_listen_socket(proc->path_proc); sfd = set_listen_socket(proc->path_proc);
if (sfd == -1){ if (sfd == -1){
handle_error("set_listen_socket"); handle_error("set_listen_socket");
} }
peer_addr_size = sizeof(struct sockaddr_un); peer_addr_size = sizeof(struct sockaddr_un);
printf("ici\n");
cfd = accept(sfd, (struct sockaddr *) &peer_addr, &peer_addr_size); cfd = accept(sfd, (struct sockaddr *) &peer_addr, &peer_addr_size);
if (cfd == -1) if (cfd == -1)
handle_error("accept"); handle_error("accept");
proc->proc_fd = cfd; proc->proc_fd = cfd;
printf("ok\n");
while (1) { while (1) {
if ((nbytes = srv_read (proc, &buf)) == -1) { if ((nbytes = app_read (proc, &buf)) == -1) {
fprintf(stdout, "MAIN_LOOP: error service_read %d\n", nbytes); fprintf(stdout, "MAIN_LOOP: error service_read %d\n", nbytes);
} }
// printf ("after read\n");
printf ("read, size %d : %s\n", nbytes, buf); if (nbytes == 0 || strncmp ("exit", buf, 4) == 0){
if (nbytes == 0){
printf("------thread shutdown------------\n"); printf("------thread shutdown------------\n");
close(cfd); close(cfd);
close(sfd); close(sfd);
free(buf); free(buf);
break; break;
} }else {
printf ("read, size %d : %s\n", nbytes, buf);
if (strncmp ("exit", buf, 4) != 0) { if ((nbytes = app_write (proc, buf, nbytes)) == -1) {
//printf ("before proc write\n");
if ((nbytes = srv_write (proc, buf, nbytes)) == -1) {
fprintf(stdout, "MAIN_LOOP: error service_write %d\n", nbytes); fprintf(stdout, "MAIN_LOOP: error service_write %d\n", nbytes);
} }
} printf("write success\n");
else {
printf("------thread shutdown------------\n");
close(cfd);
close(sfd);
free(buf);
break;
} }
} }
@ -167,7 +132,7 @@ void main_loop (struct service *srv)
perror("Server-select() error lol!"); perror("Server-select() error lol!");
exit(1); exit(1);
} }
printf("Server-select...OK\n"); //printf("Server-select...OK\n");
/*run through the existing connections looking for data to be read*/ /*run through the existing connections looking for data to be read*/
for(i = 0; i <= fdmax; i++) { for(i = 0; i <= fdmax; i++) {
@ -194,13 +159,12 @@ void main_loop (struct service *srv)
if ( nbytes == -1) { if ( nbytes == -1) {
handle_error("file_read"); handle_error("file_read");
} else if( nbytes == 0) { } else if( nbytes == 0) {
printf ("msg received (%d) : %s\n", nbytes, buf);
/* close it... */ /* close it... */
close(i); close(i);
/* remove from master set */ /* remove from master set */
FD_CLR(i, &master); FD_CLR(i, &master);
}else { }else {
//buf[BUFSIZ - 1] = '\0'; buf[BUFSIZ - 1] = '\0';
printf ("msg received (%d) : %s\n", nbytes, buf); printf ("msg received (%d) : %s\n", nbytes, buf);
if (strncmp ("exit", buf, 4) == 0) { if (strncmp ("exit", buf, 4) == 0) {
break; break;
@ -236,7 +200,6 @@ void main_loop (struct service *srv)
} }
} }
printf("ici\n");
for (i = 0; i < cnt; i++) { for (i = 0; i < cnt; i++) {
pthread_join(tab_thread[i], NULL); pthread_join(tab_thread[i], NULL);

View File

@ -28,10 +28,9 @@ do
# pid index version # pid index version
echo "${pid} 1 1" | nc -U ${REP}${SERVICE} echo "${pid} 1 1" | nc -U ${REP}${SERVICE}
sleep 1
# the purpose is to send something in the pipe # the purpose is to send something in the pipe
#cat /dev/urandom | base64 | head -n 1 > ${REP}${pid}-1-1-out #cat /dev/urandom | base64 | head -n 1 > ${REP}${pid}-1-1-out
echo "exit" | nc -U ${REP}${pid}-1-1 echo "hello frero" | nc -U ${REP}${pid}-1-1
#echo "exit" | nc -U ${REP}${pid}-1-1 #echo "exit" | nc -U ${REP}${pid}-1-1
# the service will answer with our message # the service will answer with our message

View File

@ -4,6 +4,8 @@ REP=/tmp/ipc/
SERVICE="tcpd" SERVICE="tcpd"
# pid index version # pid index version
echo "connect 127.0.0.1 6000 111111 1 1" > ${REP}${SERVICE} echo "connect 127.0.0.1 6000 111111 1 1" | nc -U ${REP}${SERVICE}
sleep 1
echo "hello frero" | nc -U ${REP}111111-1-1

View File

@ -4,5 +4,5 @@ REP=/tmp/ipc/
SERVICE="tcpd" SERVICE="tcpd"
# pid index version # pid index version
echo "exit" > ${REP}${SERVICE} echo "exit" | nc -U ${REP}${SERVICE}

View File

@ -3,4 +3,4 @@
REP=/tmp/ipc/ REP=/tmp/ipc/
SERVICE="tcpd" SERVICE="tcpd"
echo "listen 127.0.0.1 6000" > ${REP}${SERVICE} echo "listen 127.0.0.1 6000" | nc -U ${REP}${SERVICE}

View File

@ -11,22 +11,6 @@ fi
for pid in `seq 1 ${NB}` for pid in `seq 1 ${NB}`
do do
./tcpdtest.bin &
# we make the application pipes
mkfifo ${REP}${pid}-1-1-in 2>/dev/null
mkfifo ${REP}${pid}-1-1-out 2>/dev/null
echo "connect 127.0.0.1 6000 ${pid} 1 1" > ${REP}${SERVICE}
# the purpose is to send something in the pipe
cat /dev/urandom | base64 | head -n 1 > ${REP}${pid}-1-1-out
# echo "hello world" > ${REP}${pid}-1-out
sleep 2
# the the service will answer with our message
echo "pid : ${pid}"
cat ${REP}/${pid}-1-1-in
echo "exit" > ${REP}${pid}-1-1-out
done done

View File

@ -2,6 +2,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <unistd.h> #include <unistd.h>
@ -14,10 +15,13 @@
#include <linux/limits.h> #include <linux/limits.h>
#define PORT 6000 #define PORT 6000
#define BUF_SIZE 1024
#define TMPDIR "/tmp/ipc/" #define TMPDIR "/tmp/ipc/"
#define NBCLIENT 10 #define NBCLIENT 10
#define SERVICE_TCP "tcpd" #define SERVICE_TCP "tcpd"
#define LISTEN_BACKLOG 50
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)
int init_connection(const info_request *req) int init_connection(const info_request *req)
{ {
@ -65,7 +69,7 @@ void write_message(int sock, const char *buffer, size_t size_buf)
int read_message(int sock, char *buffer) int read_message(int sock, char *buffer)
{ {
return read(sock, buffer, BUF_SIZE); return read(sock, buffer, BUFSIZ);
} }
void endConnection(int sock) { void endConnection(int sock) {
@ -77,7 +81,12 @@ void printAddr(struct sockaddr_in *csin) {
printf("Port : %u\n", ntohs(csin->sin_port)); printf("Port : %u\n", ntohs(csin->sin_port));
} }
/*
* Chaque client correspond à un thread service
* Le 1er message du client indiquera le service voulu et sa version
* Etablir la connection avec le service
* Ecouter ensuite sur la socket client et socket unix pour traiter les messages
*/
void * service_thread(void * c_data) { void * service_thread(void * c_data) {
client_data *cda = (client_data*) c_data; client_data *cda = (client_data*) c_data;
char *service; char *service;
@ -85,12 +94,14 @@ void * service_thread(void * c_data) {
int clientSock = cda->sfd; int clientSock = cda->sfd;
int nbMessages = 0; int nbMessages = 0;
char *buffer = malloc (BUF_SIZE); //buffer for message
size_t nbytes = 0;
char *buffer = malloc (BUFSIZ);
if (buffer == NULL) { if (buffer == NULL) {
perror("malloc()"); perror("malloc()");
return NULL; return NULL;
} }
memset(buffer, 0, BUF_SIZE); memset(buffer, 0, BUFSIZ);
if (read_message(clientSock, buffer) == -1) { if (read_message(clientSock, buffer) == -1) {
perror("read_message()"); perror("read_message()");
@ -98,22 +109,12 @@ void * service_thread(void * c_data) {
}else { }else {
parseServiceVersion(buffer, &service, &version); parseServiceVersion(buffer, &service, &version);
} }
printf("%s\n",buffer );
printf("%s %d\n",service, version );
/* TODO : service correspond au service que le client veut utiliser /* TODO : service correspond au service que le client veut utiliser
** il faut comparer service à un tableau qui contient les services ** il faut comparer service à un tableau qui contient les services
** disponibles ** disponibles
*/ */
//path service
/*char servicePath[PATH_MAX];
memset (servicePath, 0, PATH_MAX);
if (servicePath == NULL) {
perror("malloc()");
}
snprintf(servicePath , PATH_MAX, "%s%s" , TMPDIR, service);*/
//pid index version //pid index version
char * piv = malloc(PATH_MAX); char * piv = malloc(PATH_MAX);
memset(piv , 0, PATH_MAX); memset(piv , 0, PATH_MAX);
@ -124,61 +125,23 @@ void * service_thread(void * c_data) {
struct service srv; struct service srv;
srv_init (0, NULL, NULL, &srv, service, NULL); srv_init (0, NULL, NULL, &srv, service, NULL);
app_srv_connection(&srv, piv, strlen(piv)); if (app_srv_connection(&srv, piv, strlen(piv)) == -1) {
handle_error("app_srv_connection\n");
}
free(piv); free(piv);
//write pid index version in T/I/S of service
/*int ret = file_write(servicePath, piv, strlen(piv));
if(ret == 0) {
perror("file_write()");
return NULL;
}
free(piv);*/
// gets the service path, such as /tmp/ipc/pid-index-version-in/out
/*char * pathname[2];
pathname[0] = (char*) malloc(PATH_MAX);
memset(pathname[0], 0, PATH_MAX);
if (pathname[0] == NULL) {
perror("malloc()");
}
pathname[1] = malloc(PATH_MAX);
memset(pathname[1] , 0, PATH_MAX);
if (pathname[1] == NULL) {
perror("malloc()");
}
inOutPathCreate(pathname, cda->index, version);*/
struct process p; struct process p;
app_create(&p, getpid(), cda->index, version); app_create(&p, getpid(), cda->index, version);
srv_process_print(&p); srv_process_print(&p);
sleep(1);
//create in out files printf("%s\n",p.path_proc );
/*if(fifo_create(pathname[0]) != 0) { if (proc_connection(&p) == -1){
perror("fifo_create()"); handle_error("proc_connection");
return NULL;
} }
if(fifo_create(pathname[1]) != 0) {
perror("fifo_create()");
return NULL;
}*/
//open -in fifo file
int fdin = open (p.path_in, O_RDWR);
if (fdin <= 0) {
printf("open: fd < 0\n");
perror ("open()");
return NULL;
}
//char *buf = NULL;
size_t msize;
//utilisation du select() pour surveiller la socket du client et fichier in //utilisation du select() pour surveiller la socket du client et fichier in
fd_set rdfs; fd_set rdfs;
int max = clientSock > fdin ? clientSock : fdin; int max = clientSock > p.proc_fd ? clientSock : p.proc_fd;
printf("Waitting for new messages...\n" ); printf("Waitting for new messages...\n" );
while(1) { while(1) {
@ -188,7 +151,7 @@ void * service_thread(void * c_data) {
FD_SET(clientSock, &rdfs); FD_SET(clientSock, &rdfs);
//add in file //add in file
FD_SET(fdin, &rdfs); FD_SET(p.proc_fd, &rdfs);
if(select(max + 1, &rdfs, NULL, NULL, NULL) == -1) if(select(max + 1, &rdfs, NULL, NULL, NULL) == -1)
{ {
@ -196,40 +159,44 @@ void * service_thread(void * c_data) {
exit(errno); exit(errno);
} }
if (FD_ISSET(fdin, &rdfs)){ if (FD_ISSET(p.proc_fd, &rdfs)){
if(app_read(&p, &buffer, &msize) < 0) { nbytes = app_read(&p, &buffer);
if(nbytes < 0) {
perror("app_read()"); perror("app_read()");
} }
printf("message from file in : %s\n", buffer ); printf("message from file : %s\n", buffer );
write_message(clientSock, buffer, msize); write_message(clientSock, buffer, nbytes);
nbMessages--; nbMessages--;
} else if (FD_ISSET(clientSock, &rdfs)) {
int n = read_message(clientSock, buffer); } else if (FD_ISSET(clientSock, &rdfs)) {
if(n > 0) { nbytes = read_message(clientSock, buffer);
printf("Server : message (%d bytes) : %s\n", n, buffer); if(nbytes > 0 && strncmp(buffer, "exit", 4) != 0) {
if(app_write(&p, buffer, strlen(buffer)) < 0) { printf("Server : message (%ld bytes) : %s\n", nbytes, buffer);
if(app_write(&p, buffer, nbytes) < 0) {
perror("file_write"); perror("file_write");
} }
nbMessages++; nbMessages++;
} else if (strncmp(buffer, "exit", 4) == 0 && nbMessages == 0){ }
if (strncmp(buffer, "exit", 4) == 0 && nbMessages == 0){
//message end to server //message end to server
if(app_write(&p, "exit", 4) < 0) { if(app_write(&p, "exit", 4) < 0) {
perror("file_write"); perror("file_write");
} }
//close the files descriptors
close(fdin);
close(clientSock);
printf("------thread %d shutdown----------\n\n", cda->index ); printf("------thread %d shutdown----------\n\n", cda->index );
break; break;
} }
} }
} }
//close the files descriptors
close(p.proc_fd);
close(clientSock);
free(buffer);
//release the resources
pthread_detach(pthread_self());
return NULL; return NULL;
} }
@ -299,6 +266,10 @@ void makePivMessage (char ** piv, int pid, int index, int version) {
} }
/*
* lancer le serveur, ecouter sur une l'adresse et port
* A chaque nouveau client lance un thread service
*/
void * server_thread(void * reqq) { void * server_thread(void * reqq) {
info_request *req = (info_request*) reqq; info_request *req = (info_request*) reqq;
@ -372,28 +343,18 @@ void * server_thread(void * reqq) {
pthread_join(tab_service_threads[i], NULL); pthread_join(tab_service_threads[i], NULL);
} }
printf("--------------server thread shutdown--------------- \n");
endConnection(sock); endConnection(sock);
return NULL; return NULL;
} }
/* /*
* user cans send 2 types of request to server : listen or connect * user can send 2 types of request to server : listen or connect
* listen = server for a service such as pongd * listen = server for a service such as pongd
* connect = connect to a server * connect = connect to a server
*/ */
int srv_get_new_request(const struct service *srv, info_request *req) { int srv_get_new_request(char *buf, info_request *req) {
if (srv->spath == NULL) {
return -1;
}
char *buf = NULL;
size_t msize = 0;
int ret = file_read (srv->spath, &buf, &msize);
if (ret <= 0) {
fprintf (stderr, "err: listening on %s\n", srv->spath);
return -1;
}
char *token = NULL, *saveptr = NULL; char *token = NULL, *saveptr = NULL;
char *str = NULL; char *str = NULL;
@ -411,6 +372,7 @@ int srv_get_new_request(const struct service *srv, info_request *req) {
if (i == 1) { if (i == 1) {
if(strncmp("exit", token, 4) == 0 ) { if(strncmp("exit", token, 4) == 0 ) {
strncpy(req->request, token, 4);
free(str); free(str);
return 0; return 0;
} }
@ -440,17 +402,24 @@ int srv_get_new_request(const struct service *srv, info_request *req) {
srv_process_gen (req->p, pid, index, version); srv_process_gen (req->p, pid, index, version);
} }
if (buf != NULL)
free(buf);
buf = NULL;
msize = 0;
return 1; return 1;
} }
/*
* client thread est lancé suite à une requete "connect"
* connecter à une adresse, port le 1er message indiquera le service et le version voulus
* Se mettre ensuite sur l'écoute de la socket serveur et le fichier client pour traiter les messages
*/
void * client_thread(void *reqq) { void * client_thread(void *reqq) {
info_request *req = (info_request*) reqq; info_request *req = (info_request*) reqq;
char buffer[BUF_SIZE]; /* buffer for client data */
int nbytes;
char *buffer= malloc(BUFSIZ);
if (buffer == NULL)
{
handle_error("malloc");
}
memset(buffer, 0, BUFSIZ);;
int nbMessages = 0; int nbMessages = 0;
int sock = socket(AF_INET, SOCK_STREAM, 0); int sock = socket(AF_INET, SOCK_STREAM, 0);
@ -470,57 +439,80 @@ void * client_thread(void *reqq) {
printAddr(&req->addr); printAddr(&req->addr);
write_message(sock, "pongd 5", strlen("pongd 5")); write_message(sock, "pongd 5", strlen("pongd 5"));
/*sleep(1);
write_message(sock, "is it working ???");
sleep(2);
write_message(sock, "is it working ???");*/
//open -out fifo file of client //init socket unix for server
int fdout = open (req->p->path_out, O_RDWR); int sfd;
if (fdout <= 0) { struct sockaddr_un peer_addr;
printf("open: fd < 0\n"); socklen_t peer_addr_size;
perror ("open()");
return NULL; sfd = set_listen_socket(req->p->path_proc);
if (sfd == -1){
handle_error("set_listen_socket");
} }
//utilisation du select() pour surveiller la socket du server et fichier out du client /* master file descriptor list */
fd_set rdfs; fd_set master;
/* temp file descriptor list for select() */
fd_set read_fds;
int max = sock > fdout ? sock : fdout; /* maximum file descriptor number */
int fdmax;
/* listening socket descriptor */
int listener = sfd;
/* newly accept()ed socket descriptor */
int newfd;
/* clear the master and temp sets */
FD_ZERO(&master);
FD_ZERO(&read_fds);
/* add the listener to the master set */
FD_SET(listener, &master);
FD_SET(sock, &master);
/* keep track of the biggest file descriptor */
fdmax = sock > listener ? sock : listener;
while(1) { while(1) {
FD_ZERO(&rdfs); /* copy it */
read_fds = master;
//add client's socket if(select(fdmax + 1, &read_fds, NULL, NULL, NULL) == -1)
FD_SET(sock, &rdfs);
//add in file
FD_SET(fdout, &rdfs);
if(select(max + 1, &rdfs, NULL, NULL, NULL) == -1)
{ {
perror("select()"); perror("select()");
exit(errno); exit(errno);
} }
printf("select...OK\n");
if (FD_ISSET(fdout, &rdfs)){
size_t n_read = read(fdout, &buffer, BUF_SIZE); if(FD_ISSET(listener, &read_fds)) {
if(n_read < 0) { /* handle new connections */
perror("read()"); peer_addr_size = sizeof(struct sockaddr_un);
newfd = accept(sfd, (struct sockaddr *) &peer_addr, &peer_addr_size);
if (newfd == -1) {
handle_error("accept");
} }
printf("Client : size message %ld \n",n_read ); else
write_message(sock, buffer, n_read); {
if (strncmp(buffer, "exit", 4) != 0) { printf("Server-accept() is OK...\n");
nbMessages++; FD_SET(newfd, &master); /* add to master set */
if(newfd > fdmax)
{ /* keep track of the maximum */
fdmax = newfd;
} }
req->p->proc_fd = newfd;
}
} else if (FD_ISSET(sock, &rdfs)) { }
/*
* TODO:
* Que se passe-t-il si on reçoit un message du serveur avant l'app client?
* Ou ecrit-on le message ??
*/
else if (FD_ISSET(sock, &read_fds)) {
int n = read_message(sock, buffer); int n = read_message(sock, buffer);
if(n > 0) { if(n > 0) {
printf("Client : message (%d bytes) : %s\n", n, buffer); printf("Client : message (%d bytes) : %s\n", n, buffer);
if(file_write(req->p->path_in, buffer, strlen(buffer)) < 0) { if(app_write(req->p, buffer, strlen(buffer)) < 0) {
perror("file_write"); perror("file_write");
} }
nbMessages--; nbMessages--;
@ -528,27 +520,38 @@ void * client_thread(void *reqq) {
} else if (n == 0){ } else if (n == 0){
//message end from server //message end from server
printf("server down\n"); printf("server down\n");
//close the files descriptors
close(fdout);
close(sock);
printf("------thread client shutdown----------\n"); printf("------thread client shutdown----------\n");
break; break;
} }
}else {
} nbytes = app_read (req->p, &buffer);
printf("Client : size message %d : %s\n",nbytes, buffer );
if (strncmp(buffer, "exit", 4) == 0 && nbMessages == 0) { if ( nbytes == -1) {
handle_error("file_read");
} else if( nbytes == 0) {
/* close it... */
close(req->p->proc_fd);
/* remove from master set */
FD_CLR(req->p->proc_fd, &master);
break; break;
}else {
//printf("Client : size message %d \n",nbytes );
write_message(sock, buffer, nbytes);
if (strncmp(buffer, "exit", 4) != 0) {
nbMessages++;
}
}
} }
} }
printf("------thread client shutdown----------\n"); printf("------thread client shutdown----------\n");
close(fdout); close(sfd);
close(sock); close(sock);
free(buffer);
//release the resources
pthread_detach(pthread_self());
return NULL; return NULL;
} }
@ -557,44 +560,157 @@ void request_print (const info_request *req) {
printf("%s \n",req->request); printf("%s \n",req->request);
} }
void main_loop (const struct service *srv) { /*
*Surveiller le fichier tmp/ipc/service
*Accepter 2 types de requetes :
* listen : lancer un serveur, ecouter sur un port ie "listen 127.0.0.1 6000"
* connect : connecter à une adresse, port ie "connect 127.0.0.1 6000 ${pid} 1 1"
*/
void main_loop (struct service *srv) {
//request //request
info_request req; info_request tab_req[NBCLIENT];
req.p = malloc(sizeof(struct process));
int ret; int ret;
pthread_t pidS; //pid server
pthread_t pidC; pthread_t pid_s;
//pid client
pthread_t tab_client[NBCLIENT];
int nbclient = 0;
while(1) { //init socket unix for server
ret = srv_get_new_request(srv, &req); int sfd;
struct sockaddr_un peer_addr;
socklen_t peer_addr_size;
sfd = set_listen_socket(srv->spath);
if (sfd == -1){
handle_error("set_listen_socket");
}
/* master file descriptor list */
fd_set master;
/* temp file descriptor list for select() */
fd_set read_fds;
/* maximum file descriptor number */
int fdmax;
/* listening socket descriptor */
int listener = sfd;
/* newly accept()ed socket descriptor */
int newfd;
/* buffer for client data */
char *buf = malloc(BUFSIZ);
if (buf == NULL)
{
handle_error("malloc");
}
memset(buf, 0, BUFSIZ);
int nbytes;
/* clear the master and temp sets */
FD_ZERO(&master);
FD_ZERO(&read_fds);
/* add the listener to the master set */
FD_SET(listener, &master);
//FD_SET(sfd, &master);
/* keep track of the biggest file descriptor */
fdmax = listener; /* so far, it's this one*/
for(;;) {
/* copy it */
read_fds = master;
if(select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1)
{
perror("Server-select() error lol!");
exit(1);
}
//printf("Server-select...OK\n");
if(FD_ISSET(listener, &read_fds)) {
/* handle new connections */
peer_addr_size = sizeof(struct sockaddr_un);
newfd = accept(sfd, (struct sockaddr *) &peer_addr, &peer_addr_size);
if (newfd == -1) {
handle_error("accept");
}
else
{
printf("Server-accept() is OK...\n");
FD_SET(newfd, &master); /* add to master set */
if(newfd > fdmax)
{ /* keep track of the maximum */
fdmax = newfd;
}
srv->service_fd = newfd;
}
} else {
nbytes = srv_read (srv, &buf);
if ( nbytes == -1) {
handle_error("file_read");
} else if( nbytes == 0) {
/* close it... */
close(srv->service_fd);
/* remove from master set */
FD_CLR(srv->service_fd, &master);
}else {
buf[BUFSIZ - 1] = '\0';
printf ("msg received (%d) : %s\n", nbytes, buf);
if (strncmp ("exit", buf, 4) == 0) {
break;
}
tab_req[nbclient].p = malloc(sizeof(struct process));
// -1 : error, 0 = no new process, 1 = new process
ret = srv_get_new_request (buf, &tab_req[nbclient]);
if (ret == -1) { if (ret == -1) {
perror("srv_get_new_request()"); perror("srv_get_new_request()");
exit(1); exit(1);
} else if (ret == 0) { } else if (ret == 0) {
free(req.p);
break; break;
} }
request_print(&req); request_print(&tab_req[nbclient]);
if (strcmp("listen", req.request) == 0) { if (strcmp("listen", tab_req[nbclient].request) == 0) {
int ret = pthread_create( &pidS, NULL, &server_thread, (void *) &req); int ret = pthread_create( &pid_s, NULL, &server_thread, (void *) &tab_req[nbclient]);
if (ret) { if (ret) {
perror("pthread_create()"); perror("pthread_create()");
exit(errno); exit(errno);
} else { } else {
printf("\n----------Creation of server thread ------------\n"); printf("\n----------Creation of server thread ------------\n");
} }
nbclient++;
}else { }else {
int ret = pthread_create( &pidC, NULL, &client_thread, (void *) &req); int ret = pthread_create( &tab_client[nbclient], NULL, &client_thread, (void *) &tab_req[nbclient]);
if (ret) { if (ret) {
perror("pthread_create()"); perror("pthread_create()");
exit(errno); exit(errno);
} else { } else {
printf("\n----------Creation of client thread ------------\n"); printf("\n----------Creation of client thread ------------\n");
} }
nbclient++;
} }
} }
}
}
if (pthread_cancel(pid_s) != 0) {
printf("Aucun thread correspond \n");
}
pthread_join(pid_s, NULL);
int i;
/*for (i = 0; i < nbclient; i++) {
pthread_join(tab_client[i], NULL);
}*/
for (i = 0; i < nbclient; i++) {
free(tab_req[i].p);
}
free(buf);
close(sfd);
} }
int main(int argc, char * argv[], char **env) { int main(int argc, char * argv[], char **env) {

View File

@ -48,11 +48,11 @@ void * server_thread(void *reqq);
void * client_thread(void *reqq); void * client_thread(void *reqq);
int srv_get_new_request(const struct service *srv, info_request *req); int srv_get_new_request(char *buf, info_request *req);
void request_print (const info_request *req); void request_print (const info_request *req);
void main_loop(const struct service *srv); void main_loop(struct service *srv);
#endif #endif