tcpd adapted for unix socket
This commit is contained in:
parent
f4ba61f02d
commit
b2abfb970e
@ -3,6 +3,11 @@
|
||||
#include <time.h>
|
||||
#include <errno.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)
|
||||
{
|
||||
@ -147,7 +152,7 @@ int srv_close (struct service *srv)
|
||||
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);
|
||||
memset(buf, 0, BUFSIZ);
|
||||
@ -192,26 +197,73 @@ int srv_get_new_process (const char *buf, struct process *p)
|
||||
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
|
||||
|
||||
//Init connection with unix socket
|
||||
// send the connection string to $TMP/<service>
|
||||
int app_srv_connection (struct service *srv, const char *connectionstr, size_t msize)
|
||||
{
|
||||
if (srv == NULL) {
|
||||
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)
|
||||
@ -342,3 +394,29 @@ int app_write (struct process *p, char * buf, size_t 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;
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ struct service {
|
||||
unsigned int version;
|
||||
unsigned int index;
|
||||
char spath[PATH_MAX];
|
||||
int server_fd;
|
||||
int service_fd;
|
||||
};
|
||||
|
||||
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
|
||||
, 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
|
||||
@ -50,8 +50,8 @@ int srv_get_new_process (const char *buf, struct process *proc);
|
||||
int srv_create (struct service *srv);
|
||||
int srv_close (struct service *srv);
|
||||
|
||||
int srv_read (struct process *, char ** buf);
|
||||
int srv_write (struct process *, char * buf, size_t);
|
||||
int srv_read (const struct service *, char ** buf);
|
||||
int srv_write (const struct service *, const char * buf, size_t);
|
||||
|
||||
// APPLICATION
|
||||
|
||||
@ -71,6 +71,12 @@ int file_write (int fd, const char *buf, const int m_size);
|
||||
//close socket
|
||||
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
|
||||
|
||||
#endif
|
||||
|
@ -4,38 +4,10 @@
|
||||
#include <sys/un.h>
|
||||
|
||||
#define PONGD_SERVICE_NAME "pongd"
|
||||
#define LISTEN_BACKLOG 50
|
||||
#define handle_error(msg) \
|
||||
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*/
|
||||
void * pongd_thread(void * pdata) {
|
||||
struct process *proc = (struct process*) pdata;
|
||||
@ -54,44 +26,37 @@ void * pongd_thread(void * pdata) {
|
||||
struct sockaddr_un peer_addr;
|
||||
socklen_t peer_addr_size;
|
||||
printf("%s\n", proc->path_proc);
|
||||
//app_create(proc, proc->pid, proc->index, proc->version);
|
||||
|
||||
sfd = set_listen_socket(proc->path_proc);
|
||||
if (sfd == -1){
|
||||
handle_error("set_listen_socket");
|
||||
}
|
||||
peer_addr_size = sizeof(struct sockaddr_un);
|
||||
printf("ici\n");
|
||||
|
||||
cfd = accept(sfd, (struct sockaddr *) &peer_addr, &peer_addr_size);
|
||||
if (cfd == -1)
|
||||
handle_error("accept");
|
||||
proc->proc_fd = cfd;
|
||||
printf("ok\n");
|
||||
|
||||
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);
|
||||
}
|
||||
// printf ("after read\n");
|
||||
printf ("read, size %d : %s\n", nbytes, buf);
|
||||
if (nbytes == 0){
|
||||
|
||||
if (nbytes == 0 || strncmp ("exit", buf, 4) == 0){
|
||||
printf("------thread shutdown------------\n");
|
||||
close(cfd);
|
||||
close(sfd);
|
||||
free(buf);
|
||||
break;
|
||||
}
|
||||
|
||||
if (strncmp ("exit", buf, 4) != 0) {
|
||||
//printf ("before proc write\n");
|
||||
if ((nbytes = srv_write (proc, buf, nbytes)) == -1) {
|
||||
}else {
|
||||
printf ("read, size %d : %s\n", nbytes, buf);
|
||||
if ((nbytes = app_write (proc, buf, nbytes)) == -1) {
|
||||
fprintf(stdout, "MAIN_LOOP: error service_write %d\n", nbytes);
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("------thread shutdown------------\n");
|
||||
close(cfd);
|
||||
close(sfd);
|
||||
free(buf);
|
||||
break;
|
||||
printf("write success\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -167,7 +132,7 @@ void main_loop (struct service *srv)
|
||||
perror("Server-select() error lol!");
|
||||
exit(1);
|
||||
}
|
||||
printf("Server-select...OK\n");
|
||||
//printf("Server-select...OK\n");
|
||||
|
||||
/*run through the existing connections looking for data to be read*/
|
||||
for(i = 0; i <= fdmax; i++) {
|
||||
@ -194,13 +159,12 @@ void main_loop (struct service *srv)
|
||||
if ( nbytes == -1) {
|
||||
handle_error("file_read");
|
||||
} else if( nbytes == 0) {
|
||||
printf ("msg received (%d) : %s\n", nbytes, buf);
|
||||
/* close it... */
|
||||
close(i);
|
||||
/* remove from master set */
|
||||
FD_CLR(i, &master);
|
||||
}else {
|
||||
//buf[BUFSIZ - 1] = '\0';
|
||||
buf[BUFSIZ - 1] = '\0';
|
||||
printf ("msg received (%d) : %s\n", nbytes, buf);
|
||||
if (strncmp ("exit", buf, 4) == 0) {
|
||||
break;
|
||||
@ -236,7 +200,6 @@ void main_loop (struct service *srv)
|
||||
}
|
||||
|
||||
}
|
||||
printf("ici\n");
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
pthread_join(tab_thread[i], NULL);
|
||||
|
@ -28,10 +28,9 @@ do
|
||||
# pid index version
|
||||
echo "${pid} 1 1" | nc -U ${REP}${SERVICE}
|
||||
|
||||
sleep 1
|
||||
# the purpose is to send something in the pipe
|
||||
#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
|
||||
|
||||
# the service will answer with our message
|
||||
|
@ -4,6 +4,8 @@ REP=/tmp/ipc/
|
||||
SERVICE="tcpd"
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
|
@ -4,5 +4,5 @@ REP=/tmp/ipc/
|
||||
SERVICE="tcpd"
|
||||
|
||||
# pid index version
|
||||
echo "exit" > ${REP}${SERVICE}
|
||||
echo "exit" | nc -U ${REP}${SERVICE}
|
||||
|
||||
|
@ -3,4 +3,4 @@
|
||||
REP=/tmp/ipc/
|
||||
SERVICE="tcpd"
|
||||
|
||||
echo "listen 127.0.0.1 6000" > ${REP}${SERVICE}
|
||||
echo "listen 127.0.0.1 6000" | nc -U ${REP}${SERVICE}
|
||||
|
@ -11,22 +11,6 @@ fi
|
||||
|
||||
for pid in `seq 1 ${NB}`
|
||||
do
|
||||
|
||||
# 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
|
||||
./tcpdtest.bin &
|
||||
|
||||
done
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
@ -14,10 +15,13 @@
|
||||
#include <linux/limits.h>
|
||||
|
||||
#define PORT 6000
|
||||
#define BUF_SIZE 1024
|
||||
#define TMPDIR "/tmp/ipc/"
|
||||
#define NBCLIENT 10
|
||||
#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)
|
||||
{
|
||||
@ -65,7 +69,7 @@ void write_message(int sock, const char *buffer, size_t size_buf)
|
||||
|
||||
int read_message(int sock, char *buffer)
|
||||
{
|
||||
return read(sock, buffer, BUF_SIZE);
|
||||
return read(sock, buffer, BUFSIZ);
|
||||
}
|
||||
|
||||
void endConnection(int sock) {
|
||||
@ -77,7 +81,12 @@ void printAddr(struct sockaddr_in *csin) {
|
||||
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) {
|
||||
client_data *cda = (client_data*) c_data;
|
||||
char *service;
|
||||
@ -85,12 +94,14 @@ void * service_thread(void * c_data) {
|
||||
int clientSock = cda->sfd;
|
||||
int nbMessages = 0;
|
||||
|
||||
char *buffer = malloc (BUF_SIZE);
|
||||
//buffer for message
|
||||
size_t nbytes = 0;
|
||||
char *buffer = malloc (BUFSIZ);
|
||||
if (buffer == NULL) {
|
||||
perror("malloc()");
|
||||
return NULL;
|
||||
}
|
||||
memset(buffer, 0, BUF_SIZE);
|
||||
memset(buffer, 0, BUFSIZ);
|
||||
|
||||
if (read_message(clientSock, buffer) == -1) {
|
||||
perror("read_message()");
|
||||
@ -98,22 +109,12 @@ void * service_thread(void * c_data) {
|
||||
}else {
|
||||
parseServiceVersion(buffer, &service, &version);
|
||||
}
|
||||
printf("%s\n",buffer );
|
||||
printf("%s %d\n",service, version );
|
||||
|
||||
/* TODO : service correspond au service que le client veut utiliser
|
||||
** il faut comparer service à un tableau qui contient les services
|
||||
** 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
|
||||
char * piv = malloc(PATH_MAX);
|
||||
memset(piv , 0, PATH_MAX);
|
||||
@ -124,61 +125,23 @@ void * service_thread(void * c_data) {
|
||||
|
||||
struct service srv;
|
||||
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);
|
||||
|
||||
//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;
|
||||
app_create(&p, getpid(), cda->index, version);
|
||||
srv_process_print(&p);
|
||||
|
||||
//create in out files
|
||||
/*if(fifo_create(pathname[0]) != 0) {
|
||||
perror("fifo_create()");
|
||||
return NULL;
|
||||
sleep(1);
|
||||
printf("%s\n",p.path_proc );
|
||||
if (proc_connection(&p) == -1){
|
||||
handle_error("proc_connection");
|
||||
}
|
||||
|
||||
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
|
||||
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" );
|
||||
while(1) {
|
||||
@ -188,7 +151,7 @@ void * service_thread(void * c_data) {
|
||||
FD_SET(clientSock, &rdfs);
|
||||
|
||||
//add in file
|
||||
FD_SET(fdin, &rdfs);
|
||||
FD_SET(p.proc_fd, &rdfs);
|
||||
|
||||
if(select(max + 1, &rdfs, NULL, NULL, NULL) == -1)
|
||||
{
|
||||
@ -196,40 +159,44 @@ void * service_thread(void * c_data) {
|
||||
exit(errno);
|
||||
}
|
||||
|
||||
if (FD_ISSET(fdin, &rdfs)){
|
||||
if(app_read(&p, &buffer, &msize) < 0) {
|
||||
if (FD_ISSET(p.proc_fd, &rdfs)){
|
||||
nbytes = app_read(&p, &buffer);
|
||||
if(nbytes < 0) {
|
||||
perror("app_read()");
|
||||
}
|
||||
printf("message from file in : %s\n", buffer );
|
||||
write_message(clientSock, buffer, msize);
|
||||
printf("message from file : %s\n", buffer );
|
||||
write_message(clientSock, buffer, nbytes);
|
||||
nbMessages--;
|
||||
} else if (FD_ISSET(clientSock, &rdfs)) {
|
||||
|
||||
int n = read_message(clientSock, buffer);
|
||||
if(n > 0) {
|
||||
printf("Server : message (%d bytes) : %s\n", n, buffer);
|
||||
if(app_write(&p, buffer, strlen(buffer)) < 0) {
|
||||
} else if (FD_ISSET(clientSock, &rdfs)) {
|
||||
nbytes = read_message(clientSock, buffer);
|
||||
if(nbytes > 0 && strncmp(buffer, "exit", 4) != 0) {
|
||||
printf("Server : message (%ld bytes) : %s\n", nbytes, buffer);
|
||||
if(app_write(&p, buffer, nbytes) < 0) {
|
||||
perror("file_write");
|
||||
}
|
||||
|
||||
nbMessages++;
|
||||
} else if (strncmp(buffer, "exit", 4) == 0 && nbMessages == 0){
|
||||
}
|
||||
if (strncmp(buffer, "exit", 4) == 0 && nbMessages == 0){
|
||||
//message end to server
|
||||
if(app_write(&p, "exit", 4) < 0) {
|
||||
perror("file_write");
|
||||
}
|
||||
|
||||
//close the files descriptors
|
||||
close(fdin);
|
||||
close(clientSock);
|
||||
|
||||
printf("------thread %d shutdown----------\n\n", cda->index );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
//close the files descriptors
|
||||
close(p.proc_fd);
|
||||
close(clientSock);
|
||||
free(buffer);
|
||||
|
||||
//release the resources
|
||||
pthread_detach(pthread_self());
|
||||
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) {
|
||||
info_request *req = (info_request*) reqq;
|
||||
|
||||
@ -372,28 +343,18 @@ void * server_thread(void * reqq) {
|
||||
pthread_join(tab_service_threads[i], NULL);
|
||||
}
|
||||
|
||||
printf("--------------server thread shutdown--------------- \n");
|
||||
endConnection(sock);
|
||||
|
||||
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
|
||||
* connect = connect to a server
|
||||
*/
|
||||
int srv_get_new_request(const struct service *srv, 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;
|
||||
}
|
||||
int srv_get_new_request(char *buf, info_request *req) {
|
||||
|
||||
char *token = NULL, *saveptr = NULL;
|
||||
char *str = NULL;
|
||||
@ -411,6 +372,7 @@ int srv_get_new_request(const struct service *srv, info_request *req) {
|
||||
|
||||
if (i == 1) {
|
||||
if(strncmp("exit", token, 4) == 0 ) {
|
||||
strncpy(req->request, token, 4);
|
||||
free(str);
|
||||
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);
|
||||
}
|
||||
|
||||
if (buf != NULL)
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
msize = 0;
|
||||
|
||||
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) {
|
||||
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 sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
@ -470,57 +439,80 @@ void * client_thread(void *reqq) {
|
||||
printAddr(&req->addr);
|
||||
|
||||
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
|
||||
int fdout = open (req->p->path_out, O_RDWR);
|
||||
if (fdout <= 0) {
|
||||
printf("open: fd < 0\n");
|
||||
perror ("open()");
|
||||
return NULL;
|
||||
//init socket unix for server
|
||||
int sfd;
|
||||
struct sockaddr_un peer_addr;
|
||||
socklen_t peer_addr_size;
|
||||
|
||||
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
|
||||
fd_set rdfs;
|
||||
/* master file descriptor list */
|
||||
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) {
|
||||
FD_ZERO(&rdfs);
|
||||
/* copy it */
|
||||
read_fds = master;
|
||||
|
||||
//add client's socket
|
||||
FD_SET(sock, &rdfs);
|
||||
|
||||
//add in file
|
||||
FD_SET(fdout, &rdfs);
|
||||
|
||||
if(select(max + 1, &rdfs, NULL, NULL, NULL) == -1)
|
||||
if(select(fdmax + 1, &read_fds, NULL, NULL, NULL) == -1)
|
||||
{
|
||||
perror("select()");
|
||||
exit(errno);
|
||||
}
|
||||
printf("select...OK\n");
|
||||
|
||||
if (FD_ISSET(fdout, &rdfs)){
|
||||
size_t n_read = read(fdout, &buffer, BUF_SIZE);
|
||||
if(n_read < 0) {
|
||||
perror("read()");
|
||||
|
||||
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");
|
||||
}
|
||||
printf("Client : size message %ld \n",n_read );
|
||||
write_message(sock, buffer, n_read);
|
||||
if (strncmp(buffer, "exit", 4) != 0) {
|
||||
nbMessages++;
|
||||
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;
|
||||
}
|
||||
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);
|
||||
if(n > 0) {
|
||||
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");
|
||||
}
|
||||
nbMessages--;
|
||||
@ -528,27 +520,38 @@ void * client_thread(void *reqq) {
|
||||
} else if (n == 0){
|
||||
//message end from server
|
||||
printf("server down\n");
|
||||
|
||||
//close the files descriptors
|
||||
close(fdout);
|
||||
close(sock);
|
||||
|
||||
printf("------thread client shutdown----------\n");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (strncmp(buffer, "exit", 4) == 0 && nbMessages == 0) {
|
||||
break;
|
||||
}
|
||||
}else {
|
||||
nbytes = app_read (req->p, &buffer);
|
||||
printf("Client : size message %d : %s\n",nbytes, buffer );
|
||||
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;
|
||||
}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");
|
||||
close(fdout);
|
||||
close(sfd);
|
||||
close(sock);
|
||||
free(buffer);
|
||||
|
||||
//release the resources
|
||||
pthread_detach(pthread_self());
|
||||
return NULL;
|
||||
|
||||
}
|
||||
@ -557,44 +560,157 @@ void request_print (const info_request *req) {
|
||||
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
|
||||
info_request req;
|
||||
req.p = malloc(sizeof(struct process));
|
||||
info_request tab_req[NBCLIENT];
|
||||
int ret;
|
||||
pthread_t pidS;
|
||||
pthread_t pidC;
|
||||
//pid server
|
||||
pthread_t pid_s;
|
||||
//pid client
|
||||
pthread_t tab_client[NBCLIENT];
|
||||
int nbclient = 0;
|
||||
|
||||
while(1) {
|
||||
ret = srv_get_new_request(srv, &req);
|
||||
if (ret == -1) {
|
||||
perror("srv_get_new_request()");
|
||||
//init socket unix for server
|
||||
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);
|
||||
} else if (ret == 0) {
|
||||
free(req.p);
|
||||
break;
|
||||
}
|
||||
//printf("Server-select...OK\n");
|
||||
|
||||
request_print(&req);
|
||||
|
||||
if (strcmp("listen", req.request) == 0) {
|
||||
int ret = pthread_create( &pidS, NULL, &server_thread, (void *) &req);
|
||||
if (ret) {
|
||||
perror("pthread_create()");
|
||||
exit(errno);
|
||||
} else {
|
||||
printf("\n----------Creation of server thread ------------\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 {
|
||||
int ret = pthread_create( &pidC, NULL, &client_thread, (void *) &req);
|
||||
if (ret) {
|
||||
perror("pthread_create()");
|
||||
exit(errno);
|
||||
} else {
|
||||
printf("\n----------Creation of client thread ------------\n");
|
||||
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) {
|
||||
perror("srv_get_new_request()");
|
||||
exit(1);
|
||||
} else if (ret == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
request_print(&tab_req[nbclient]);
|
||||
|
||||
if (strcmp("listen", tab_req[nbclient].request) == 0) {
|
||||
int ret = pthread_create( &pid_s, NULL, &server_thread, (void *) &tab_req[nbclient]);
|
||||
if (ret) {
|
||||
perror("pthread_create()");
|
||||
exit(errno);
|
||||
} else {
|
||||
printf("\n----------Creation of server thread ------------\n");
|
||||
}
|
||||
nbclient++;
|
||||
}else {
|
||||
int ret = pthread_create( &tab_client[nbclient], NULL, &client_thread, (void *) &tab_req[nbclient]);
|
||||
if (ret) {
|
||||
perror("pthread_create()");
|
||||
exit(errno);
|
||||
} else {
|
||||
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) {
|
||||
|
@ -48,11 +48,11 @@ void * server_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 main_loop(const struct service *srv);
|
||||
void main_loop(struct service *srv);
|
||||
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user