Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /******************************************************************************/
- #include <arpa/inet.h>
- #include <sys/ioctl.h>
- #include <sys/select.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- /******************************************************************************/
- #include "p2p_srv.h"
- /******************************************************************************/
- void p2p_srv_add_cli_list(const struct sockaddr_in* sin, const int s, struct p2p_cli_list* list, fd_set* fds, int* max)
- {
- struct p2p_cli* cli = NULL;
- /* Allocate memory */
- if ((cli = malloc(sizeof(struct p2p_cli))))
- {
- printf("p2p_srv_add_cli_list(): %i bytes allocated at 0x%.8x\n", sizeof(struct p2p_cli), (unsigned int)cli);
- /* Configure first client */
- p2p_srv_conf_first_cli(list, cli);
- /* Add client to the list */
- memcpy(&cli->sin, sin, sizeof(struct sockaddr_in));
- cli->next = NULL;
- cli->prev = list->old;
- if (list->old)
- {
- printf("p2p_srv_add_cli_list(): 0x%.8x contain now 0x%.8x as next client\n", (unsigned int)list->old, (unsigned int)cli);
- list->old->next = cli;
- }
- list->old = cli;
- cli->s = s;
- /* Monitor socket */
- p2p_srv_monitor_s(s, fds, max);
- }
- else
- {
- printf("p2p_srv_add_cli_list(): failed to allocate %i bytes\n", sizeof(struct p2p_cli));
- /* Close socket */
- if (close(s) != -1)
- printf("p2p_srv_add_cli_list(): socket %i closed with %s:%i\n", s, inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
- }
- }
- /******************************************************************************/
- void p2p_srv_chk_new_msg_on_cli(const int s, struct p2p_cli_list* list, fd_set* fds_tmp, fd_set* fds, int* max)
- {
- struct p2p_cli* cli = NULL;
- int len = 0;
- /* Check new message on each client */
- for (cli = list->first; cli; cli = cli->next)
- {
- if (FD_ISSET(cli->s, fds_tmp))
- {
- printf("p2p_srv_chk_new_msg_on_cli(): new message on socket %i with %s:%i\n", cli->s, inet_ntoa(cli->sin.sin_addr), ntohs(cli->sin.sin_port));
- /* Get message length */
- if (ioctl(cli->s, FIONREAD, &len) != -1)
- {
- printf("p2p_srv_chk_new_msg_on_cli(): %i bytes received on socket %i with %s:%i\n", len, cli->s, inet_ntoa(cli->sin.sin_addr), ntohs(cli->sin.sin_port));
- /* Disconnection */
- if (!len)
- p2p_srv_discon(list, s, cli, fds, max);
- }
- }
- }
- }
- /******************************************************************************/
- void p2p_srv_stop_monitor_s(const struct p2p_cli_list* list, const int s, const int ss, fd_set* fds, int* max)
- {
- /* Stop monitor socket */
- FD_CLR(s, fds);
- /* Decrease socket limit */
- p2p_srv_dec_s_limit(list, s, ss, max);
- }
- /******************************************************************************/
- void p2p_srv_discon(const struct p2p_cli_list* list, const int s, struct p2p_cli* cli, fd_set* fds, int* max)
- {
- /* Close socket */
- if (close(cli->s) != -1)
- printf("p2p_srv_discon(): socket %i closed with %s:%i\n", cli->s, inet_ntoa(cli->sin.sin_addr), ntohs(cli->sin.sin_port));
- /* Stop monitor socket */
- p2p_srv_stop_monitor_s(list, cli->s, s, fds, max);
- }
- /******************************************************************************/
- void p2p_srv_wait_msg(const int s, struct p2p_cli_list* list, fd_set* fds, int* max)
- {
- struct sockaddr_in csin;
- socklen_t clen = 0;
- fd_set fds_tmp;
- int cs = 0;
- /* Save fds */
- fds_tmp = *fds;
- /* Select sockets */
- if (select(*max + 1, &fds_tmp, NULL, NULL, NULL) != -1)
- {
- printf("p2p_srv_wait_msg(): %i sockets selected\n", *max);
- /* Check new client on server socket */
- if (FD_ISSET(s, &fds_tmp))
- {
- printf("p2p_srv_wait_msg(): new client on socket %i\n", s);
- /* Compute client length */
- p2p_srv_compute_cli_len(&csin, &clen);
- /* Accept client */
- if ((cs = accept(s, (struct sockaddr*)&csin, &clen)) != -1)
- {
- printf("p2p_srv_wait_msg(): socket %i opened with %s:%i\n", cs, inet_ntoa(csin.sin_addr), ntohs(csin.sin_port));
- /* Add client to the list */
- p2p_srv_add_cli_list(&csin, cs, list, fds, max);
- }
- }
- else
- {
- /* Check new message on each client */
- p2p_srv_chk_new_msg_on_cli(s, list, &fds_tmp, fds, max);
- }
- }
- }
- /******************************************************************************/
- void p2p_srv_dec_s_limit(const struct p2p_cli_list* list, const int s, const int ss, int* max)
- {
- struct p2p_cli* cli = NULL;
- /* Decrease socket limit */
- if (s == *max)
- {
- *max = ss;
- for (cli = list->first; cli; cli = cli->next)
- if (cli->s != s && cli->s > *max)
- *max = cli->s;
- }
- printf("p2p_srv_dec_s_limit(): socket limit is now %i\n", *max);
- }
- /******************************************************************************/
- void p2p_srv_conf_first_cli(struct p2p_cli_list* list, struct p2p_cli* cli)
- {
- /* Configure first client */
- if (!list->old)
- {
- printf("p2p_srv_conf_first_cli(): first client is now at 0x%.8x\n", (unsigned int)cli);
- list->first = cli;
- }
- }
- /******************************************************************************/
- void p2p_srv_conf_port(const unsigned short port, struct sockaddr_in* sin)
- {
- /* Configure port */
- memset(sin, 0, sizeof(struct sockaddr_in));
- sin->sin_port = htons(port);
- sin->sin_family = AF_INET;
- }
- /******************************************************************************/
- void p2p_srv_compute_cli_len(struct sockaddr_in* sin, socklen_t* len)
- {
- /* Compute length */
- memset(sin, 0, sizeof(struct sockaddr_in));
- *len = sizeof(struct sockaddr_in);
- }
- /******************************************************************************/
- void p2p_srv_monitor_s(const int s, fd_set* fds, int* max)
- {
- /* Monitor socket */
- FD_SET(s, fds);
- /* Incease socket limit */
- p2p_srv_inc_s_limit(s, max);
- }
- /******************************************************************************/
- void p2p_srv_inc_s_limit(const int s, int* max)
- {
- /* Configure socket limit */
- if (s > *max)
- {
- printf("p2p_srv_inc_s_limit(): socket limit is now %i\n", s);
- *max = s;
- }
- }
- /******************************************************************************/
- void p2p_srv_run(const unsigned short port)
- {
- struct p2p_cli_list list;
- struct sockaddr_in sin;
- fd_set fds;
- int max = 0;
- int s = 0;
- /* Clean structure */
- memset(&list, 0, sizeof(struct p2p_cli_list));
- /* Create socket */
- if ((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) != -1)
- {
- printf("p2p_srv_run(): socket %i created\n", s);
- /* Configure port */
- p2p_srv_conf_port(port, &sin);
- /* Bind socket */
- if (bind(s, (struct sockaddr*)&sin, sizeof(struct sockaddr_in)) != -1)
- {
- printf("p2p_srv_run(): socket %i binded on %s:%i\n", s, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
- /* Listen socket */
- if (listen(s, SOMAXCONN) != -1)
- {
- printf("p2p_srv_run(): socket %i listened with a backlog of %i\n", s, SOMAXCONN);
- /* Monitor socket */
- FD_ZERO(&fds);
- p2p_srv_monitor_s(s, &fds, &max);
- /* Wait message */
- while (1)
- p2p_srv_wait_msg(s, &list, &fds, &max);
- }
- }
- /* Close socket */
- if (close(s) != -1)
- printf("p2p_srv_run(): socket %i closed\n", s);
- }
- }
- /******************************************************************************/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement