Changeset bf4c7ff6 in rtems


Ignore:
Timestamp:
Oct 10, 2018, 7:04:47 AM (7 months ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
0f0e130
Parents:
1c567c5
git-author:
Sebastian Huber <sebastian.huber@…> (10/10/18 07:04:47)
git-committer:
Sebastian Huber <sebastian.huber@…> (10/10/18 12:06:28)
Message:

telnetd: Create server socket at start

Update #3543.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpukit/telnetd/telnetd.c

    r1c567c5 rbf4c7ff6  
    7373struct telnetd_context {
    7474  rtems_telnetd_config_table config;
     75  int                        server_socket;
    7576  uint16_t                   active_clients;
    7677};
     
    8182} uni_sa;
    8283
    83 static int sockpeername(int sock, char *buf, int bufsz);
    84 
    8584/***********************************************************/
    8685static telnetd_context telnetd_instance;
    8786
    88 static telnetd_session *grab_a_Connection(
    89   telnetd_context *ctx,
    90   int des_socket,
    91   uni_sa *srv,
    92   char *peername,
    93   int sz
    94 )
     87static telnetd_session *grab_a_Connection(telnetd_context *ctx)
    9588{
    9689  telnetd_session *session;
    97   socklen_t size_adr = sizeof(srv->sin);
     90  uni_sa peer;
     91  socklen_t address_len;
    9892  int acp_sock;
    9993
     
    108102  }
    109103
    110   acp_sock = accept(des_socket,&srv->sa,&size_adr);
     104  address_len = sizeof(peer.sin);
     105  acp_sock = accept(ctx->server_socket, &peer.sa, &address_len);
    111106  if (acp_sock<0) {
    112107    perror("telnetd:accept");
     
    122117  }
    123118
    124   if (sockpeername(acp_sock, peername, sz))
    125     strncpy(peername, "<UNKNOWN>", sz);
     119  if (
     120    inet_ntop(
     121      AF_INET,
     122      &peer.sin.sin_addr,
     123      session->peername,
     124      sizeof(session->peername)
     125    ) == NULL
     126  ) {
     127    strlcpy(session->peername, "<UNKNOWN>", sizeof(session->peername));
     128  }
    126129
    127130#ifdef PARANOIA
    128131  syslog(LOG_DAEMON | LOG_INFO,
    129132      "telnetd: accepted connection from %s on %s",
    130       peername,
     133      session->peername,
    131134      session->pty.name);
    132135#endif
     
    138141
    139142
    140 static void release_a_Connection(telnetd_context *ctx, const char *devname,
    141   const char *peername, FILE **pstd, int n)
    142 {
    143 
     143static void release_a_Connection(
     144  telnetd_context *ctx,
     145  telnetd_session *session,
     146  FILE **pstd,
     147  int n
     148)
     149{
    144150#ifdef PARANOIA
    145   syslog( LOG_DAEMON | LOG_INFO,
    146       "telnetd: releasing connection from %s on %s",
    147       peername,
    148       devname );
     151  syslog(
     152    LOG_DAEMON | LOG_INFO,
     153    "telnetd: releasing connection from %s on %s",
     154    session->peername,
     155    session->pty.name
     156  );
    149157#endif
    150158
     
    154162    if (pstd[n]) fclose(pstd[n]);
    155163
    156   unlink(devname);
    157 }
    158 
    159 static int sockpeername(int sock, char *buf, int bufsz)
    160 {
    161   uni_sa peer;
    162   int    rval = sock < 0;
    163   socklen_t len  = sizeof(peer.sin);
    164 
    165   if ( !rval )
    166     rval = getpeername(sock, &peer.sa, &len);
    167 
    168   if ( !rval )
    169     rval = !inet_ntop( AF_INET, &peer.sin.sin_addr, buf, bufsz );
    170 
    171   return rval;
     164  unlink(session->pty.name);
    172165}
    173166
     
    206199telnetd_server_task(rtems_task_argument arg)
    207200{
    208   int                des_socket;
    209   uni_sa             srv;
    210   char               peername[16];
    211   int                i=1;
    212   int                size_adr;
    213201  telnetd_session   *session = NULL;
    214202  rtems_id           task_id;
    215203  telnetd_context   *ctx = (telnetd_context *) arg;
    216 
    217   if ((des_socket=socket(PF_INET,SOCK_STREAM,0))<0) {
    218     perror("telnetd:socket");
    219     rtems_task_exit();
    220   };
    221   (void)setsockopt(des_socket,SOL_SOCKET,SO_KEEPALIVE,&i,sizeof(i));
    222 
    223   memset(&srv,0,sizeof(srv));
    224   srv.sin.sin_family=AF_INET;
    225   srv.sin.sin_port=htons(23);
    226   size_adr=sizeof(srv.sin);
    227   if ((bind(des_socket,&srv.sa,size_adr))<0) {
    228     perror("telnetd:bind");
    229     close(des_socket);
    230     rtems_task_exit();
    231   };
    232   if ((listen(des_socket,5))<0) {
    233     perror("telnetd:listen");
    234           close(des_socket);
    235     rtems_task_exit();
    236   };
    237204
    238205  /* we don't redirect stdio as this probably
     
    240207   */
    241208  do {
    242     session = grab_a_Connection(ctx, des_socket, &srv, peername,
    243       sizeof(peername));
     209    session = grab_a_Connection(ctx);
    244210
    245211    if (session == NULL) {
     
    248214      continue;
    249215    }
    250 
    251     strncpy(session->peername, peername, sizeof(session->peername));
    252216
    253217    task_id = telnetd_spawn_task(
     
    270234      if ( !(dummy=fopen(session->pty.name,"r+")) )
    271235        perror("Unable to dummy open the pty, losing a slot :-(");
    272       release_a_Connection(ctx, session->pty.name, peername, &dummy, 1);
     236      release_a_Connection(ctx, session, &dummy, 1);
    273237      free(session);
    274238      sleep(2); /* don't accept connections too fast */
    275239    }
    276240  } while(1);
    277 
    278   /* TODO: how to free the connection semaphore? But then -
    279    *       stopping the daemon is probably only needed during
    280    *       development/debugging.
    281    *       Finalizer code should collect all the connection semaphore
    282    *       counts and eventually clean up...
    283    */
    284   close(des_socket);
     241}
     242
     243static void telnetd_destroy_context(telnetd_context *ctx)
     244{
     245  if (ctx->server_socket >= 0) {
     246    close(ctx->server_socket);
     247  }
     248}
     249
     250static rtems_status_code telnetd_create_server_socket(telnetd_context *ctx)
     251{
     252  uni_sa srv;
     253  socklen_t address_len;
     254  int enable;
     255
     256  ctx->server_socket = socket(PF_INET, SOCK_STREAM, 0);
     257  if (ctx->server_socket < 0) {
     258    syslog(LOG_DAEMON | LOG_ERR, "telnetd: cannot create server socket");
     259    return RTEMS_UNSATISFIED;
     260  }
     261
     262  enable = 1;
     263  (void)setsockopt(
     264    ctx->server_socket,
     265    SOL_SOCKET,
     266    SO_KEEPALIVE,
     267    &enable,
     268    sizeof(enable)
     269  );
     270
     271  memset(&srv, 0, sizeof(srv));
     272  srv.sin.sin_family = AF_INET;
     273  srv.sin.sin_port = htons(23);
     274  address_len = sizeof(srv.sin);
     275
     276  if (bind(ctx->server_socket, &srv.sa, address_len) != 0) {
     277    syslog(LOG_DAEMON | LOG_ERR, "telnetd: cannot bind server socket");
     278    return RTEMS_RESOURCE_IN_USE;
     279  };
     280
     281  if (listen(ctx->server_socket, ctx->config.client_maximum) != 0) {
     282    syslog(LOG_DAEMON | LOG_ERR, "telnetd: cannot listen on server socket");
     283    return RTEMS_UNSATISFIED;
     284  };
     285
     286  return RTEMS_SUCCESSFUL;
    285287}
    286288
     
    289291  telnetd_context *ctx = &telnetd_instance;
    290292  rtems_id task_id;
     293  rtems_status_code sc;
    291294
    292295  if (config->command == NULL) {
     
    319322  if (ctx->config.client_maximum == 0) {
    320323    ctx->config.client_maximum = 5;
     324  }
     325
     326  sc = telnetd_create_server_socket(ctx);
     327  if (sc != RTEMS_SUCCESSFUL) {
     328    telnetd_destroy_context(ctx);
     329    return sc;
    321330  }
    322331
     
    331340    ctx->config.command = NULL;
    332341    syslog(LOG_DAEMON | LOG_ERR, "telnetd: cannot create server task");
     342    telnetd_destroy_context(ctx);
    333343    return RTEMS_UNSATISFIED;
    334344  }
     
    405415
    406416cleanup:
    407   release_a_Connection(ctx, session->pty.name, session->peername, nstd, i);
     417  release_a_Connection(ctx, session, nstd, i);
    408418  free(session);
    409419}
Note: See TracChangeset for help on using the changeset viewer.