Advertisement
Guest User

Untitled

a guest
Jun 23rd, 2017
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.31 KB | None | 0 0
  1. /******************************************************************************/
  2. #include <arpa/inet.h>
  3. #include <sys/ioctl.h>
  4. #include <sys/select.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <unistd.h>
  9. /******************************************************************************/
  10. #include "p2p_srv.h"
  11. /******************************************************************************/
  12. void p2p_srv_add_cli_list(const struct sockaddr_in* sin, const int s, struct p2p_cli_list* list, fd_set* fds, int* max)
  13. {
  14.     struct p2p_cli* cli =   NULL;
  15.    
  16.     /* Allocate memory */
  17.     if ((cli = malloc(sizeof(struct p2p_cli))))
  18.     {
  19.         printf("p2p_srv_add_cli_list(): %i bytes allocated at 0x%.8x\n", sizeof(struct p2p_cli), (unsigned int)cli);
  20.        
  21.         /* Configure first client */
  22.         p2p_srv_conf_first_cli(list, cli);
  23.        
  24.         /* Add client to the list */
  25.         memcpy(&cli->sin, sin, sizeof(struct sockaddr_in));
  26.         cli->next = NULL;
  27.         cli->prev = list->old;
  28.        
  29.         if (list->old)
  30.         {
  31.             printf("p2p_srv_add_cli_list(): 0x%.8x contain now 0x%.8x as next client\n", (unsigned int)list->old, (unsigned int)cli);
  32.             list->old->next = cli;
  33.         }
  34.        
  35.         list->old = cli;
  36.         cli->s = s;
  37.        
  38.         /* Monitor socket */
  39.         p2p_srv_monitor_s(s, fds, max);
  40.     }
  41.     else
  42.     {
  43.         printf("p2p_srv_add_cli_list(): failed to allocate %i bytes\n", sizeof(struct p2p_cli));
  44.        
  45.         /* Close socket */
  46.         if (close(s) != -1)
  47.             printf("p2p_srv_add_cli_list(): socket %i closed with %s:%i\n", s, inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
  48.     }
  49. }
  50. /******************************************************************************/
  51. 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)
  52. {
  53.     struct p2p_cli* cli =   NULL;
  54.     int             len =   0;
  55.    
  56.     /* Check new message on each client */
  57.     for (cli = list->first; cli; cli = cli->next)
  58.     {
  59.         if (FD_ISSET(cli->s, fds_tmp))
  60.         {
  61.             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));
  62.            
  63.             /* Get message length */
  64.             if (ioctl(cli->s, FIONREAD, &len) != -1)
  65.             {
  66.                 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));
  67.                
  68.                 /* Disconnection */
  69.                 if (!len)
  70.                     p2p_srv_discon(list, s, cli, fds, max);
  71.             }
  72.         }
  73.     }
  74. }
  75. /******************************************************************************/
  76. void p2p_srv_stop_monitor_s(const struct p2p_cli_list* list, const int s, const int ss, fd_set* fds, int* max)
  77. {
  78.     /* Stop monitor socket */
  79.     FD_CLR(s, fds);
  80.    
  81.     /* Decrease socket limit */
  82.     p2p_srv_dec_s_limit(list, s, ss, max);
  83. }
  84. /******************************************************************************/
  85. void p2p_srv_discon(const struct p2p_cli_list* list, const int s, struct p2p_cli* cli, fd_set* fds, int* max)
  86. {
  87.     /* Close socket */
  88.     if (close(cli->s) != -1)
  89.         printf("p2p_srv_discon(): socket %i closed with %s:%i\n", cli->s, inet_ntoa(cli->sin.sin_addr), ntohs(cli->sin.sin_port));
  90.    
  91.     /* Stop monitor socket */
  92.     p2p_srv_stop_monitor_s(list, cli->s, s, fds, max);
  93. }
  94. /******************************************************************************/
  95. void p2p_srv_wait_msg(const int s, struct p2p_cli_list* list, fd_set* fds, int* max)
  96. {
  97.     struct sockaddr_in  csin;
  98.     socklen_t           clen    =   0;
  99.     fd_set              fds_tmp;
  100.     int                 cs      =   0;
  101.    
  102.     /* Save fds */
  103.     fds_tmp = *fds;
  104.    
  105.     /* Select sockets */
  106.     if (select(*max + 1, &fds_tmp, NULL, NULL, NULL) != -1)
  107.     {
  108.         printf("p2p_srv_wait_msg(): %i sockets selected\n", *max);
  109.        
  110.         /* Check new client on server socket */
  111.         if (FD_ISSET(s, &fds_tmp))
  112.         {
  113.             printf("p2p_srv_wait_msg(): new client on socket %i\n", s);
  114.            
  115.             /* Compute client length */
  116.             p2p_srv_compute_cli_len(&csin, &clen);
  117.            
  118.             /* Accept client */
  119.             if ((cs = accept(s, (struct sockaddr*)&csin, &clen)) != -1)
  120.             {
  121.                 printf("p2p_srv_wait_msg(): socket %i opened with %s:%i\n", cs, inet_ntoa(csin.sin_addr), ntohs(csin.sin_port));
  122.                
  123.                 /* Add client to the list */
  124.                 p2p_srv_add_cli_list(&csin, cs, list, fds, max);
  125.             }
  126.         }
  127.         else
  128.         {
  129.             /* Check new message on each client */
  130.             p2p_srv_chk_new_msg_on_cli(s, list, &fds_tmp, fds, max);
  131.         }
  132.     }
  133. }
  134. /******************************************************************************/
  135. void p2p_srv_dec_s_limit(const struct p2p_cli_list* list, const int s, const int ss, int* max)
  136. {
  137.     struct p2p_cli* cli =   NULL;
  138.    
  139.     /* Decrease socket limit */
  140.     if (s == *max)
  141.     {
  142.         *max = ss;
  143.        
  144.         for (cli = list->first; cli; cli = cli->next)
  145.             if (cli->s != s && cli->s > *max)
  146.                 *max = cli->s;
  147.     }
  148.    
  149.     printf("p2p_srv_dec_s_limit(): socket limit is now %i\n", *max);
  150. }
  151. /******************************************************************************/
  152. void p2p_srv_conf_first_cli(struct p2p_cli_list* list, struct p2p_cli* cli)
  153. {
  154.     /* Configure first client */
  155.     if (!list->old)
  156.     {
  157.         printf("p2p_srv_conf_first_cli(): first client is now at 0x%.8x\n", (unsigned int)cli);
  158.         list->first = cli;
  159.     }
  160. }
  161. /******************************************************************************/
  162. void p2p_srv_conf_port(const unsigned short port, struct sockaddr_in* sin)
  163. {
  164.     /* Configure port */
  165.     memset(sin, 0, sizeof(struct sockaddr_in));
  166.     sin->sin_port = htons(port);
  167.     sin->sin_family = AF_INET;
  168. }
  169. /******************************************************************************/
  170. void p2p_srv_compute_cli_len(struct sockaddr_in* sin, socklen_t* len)
  171. {
  172.     /* Compute length */
  173.     memset(sin, 0, sizeof(struct sockaddr_in));
  174.     *len = sizeof(struct sockaddr_in);
  175. }
  176. /******************************************************************************/
  177. void p2p_srv_monitor_s(const int s, fd_set* fds, int* max)
  178. {
  179.     /* Monitor socket */
  180.     FD_SET(s, fds);
  181.    
  182.     /* Incease socket limit */
  183.     p2p_srv_inc_s_limit(s, max);
  184. }
  185. /******************************************************************************/
  186. void p2p_srv_inc_s_limit(const int s, int* max)
  187. {
  188.     /* Configure socket limit */
  189.     if (s > *max)
  190.     {
  191.         printf("p2p_srv_inc_s_limit(): socket limit is now %i\n", s);
  192.         *max = s;
  193.     }
  194. }
  195. /******************************************************************************/
  196. void p2p_srv_run(const unsigned short port)
  197. {
  198.     struct p2p_cli_list list;
  199.     struct sockaddr_in  sin;
  200.     fd_set              fds;
  201.     int                 max =   0;
  202.     int                 s   =   0;
  203.    
  204.     /* Clean structure */
  205.     memset(&list, 0, sizeof(struct p2p_cli_list));
  206.    
  207.     /* Create socket */
  208.     if ((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) != -1)
  209.     {
  210.         printf("p2p_srv_run(): socket %i created\n", s);
  211.        
  212.         /* Configure port */
  213.         p2p_srv_conf_port(port, &sin);
  214.        
  215.         /* Bind socket */
  216.         if (bind(s, (struct sockaddr*)&sin, sizeof(struct sockaddr_in)) != -1)
  217.         {
  218.             printf("p2p_srv_run(): socket %i binded on %s:%i\n", s, inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
  219.            
  220.             /* Listen socket */
  221.             if (listen(s, SOMAXCONN) != -1)
  222.             {
  223.                 printf("p2p_srv_run(): socket %i listened with a backlog of %i\n", s, SOMAXCONN);
  224.                
  225.                 /* Monitor socket */
  226.                 FD_ZERO(&fds);
  227.                 p2p_srv_monitor_s(s, &fds, &max);
  228.                
  229.                 /* Wait message */
  230.                 while (1)
  231.                     p2p_srv_wait_msg(s, &list, &fds, &max);
  232.             }
  233.         }
  234.        
  235.         /* Close socket */
  236.         if (close(s) != -1)
  237.             printf("p2p_srv_run(): socket %i closed\n", s);
  238.     }
  239. }
  240. /******************************************************************************/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement