]> arthur.barton.de Git - netatalk.git/commitdiff
Enhance handling of connection attempts when hitting the connection limit
authorRalph Boehme <sloowfranklin@gmail.com>
Mon, 23 Sep 2013 09:27:29 +0000 (11:27 +0200)
committerRalph Boehme <sloowfranklin@gmail.com>
Mon, 23 Sep 2013 09:27:29 +0000 (11:27 +0200)
Bug #529.

NEWS
etc/afpd/auth.c
include/atalk/afp.h
include/atalk/globals.h
libatalk/dsi/dsi_getsess.c

diff --git a/NEWS b/NEWS
index cde45f142432516847548ca48dac03ccc3a4ea8a..6416a89ae0095d6e9bb69a3657f1537f62aee8ac 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,8 @@ Changes in 3.0.6
        a volume is stored in the volume root of a share in a directory
        .AppleDB like in Netatalk 2. Defaults to false. From FR#84.
 * FIX: Small fix in the DSI tickle handling. Bug #528.
+* UPD: Enhance handling of connection attempts when hitting the
+       connection limit. Bug #529.
 
 Changes in 3.0.5
 ================
index bec624dc6cd32efc72b9838381a5b8f12ad6593b..ed08bbfa8532fec275ac8c92d5ddc58d1c2a88da 100644 (file)
@@ -222,6 +222,11 @@ static int login(AFPObj *obj, struct passwd *pwd, void (*logout)(void), int expi
         return AFPERR_NOTAUTH;
     }
 
+    if (obj->cnx_cnt >= obj->cnx_max) {
+        LOG(log_error, logtype_dsi, "login: too many connections, limit: %d", obj->cnx_max);
+        return AFPERR_MAXSESS;
+    }
+
     LOG(log_note, logtype_afpd, "%s Login by %s",
         afp_versions[afp_version_index].av_name, pwd->pw_name);
 
index 76315aa41acd661b4e7b8b6c8dc454496ce6b38c..0c2489ea906d4d884c1a2b87f41c971db45e26e4 100644 (file)
@@ -49,6 +49,7 @@ typedef uint16_t AFPUserBytes;
 #define AFPSRVRINFO_FASTBOZO     (1<<15) /* fast copying */
 
 #define AFP_OK         0
+#define AFPERR_MAXSESS  -1068   /* maximum number of allowed sessions reached */
 #define AFPERR_DID1     -4000   /* not an afp error DID is 1*/
 #define AFPERR_ACCESS  -5000   /* permission denied */
 #define AFPERR_AUTHCONT        -5001   /* logincont */
index 61cf247fe9987ce9f1cbe74d621c7eac4ed981cb..e1b5454b366486c3f4f6f3ae204cf28fbb035ad0 100644 (file)
@@ -138,6 +138,7 @@ typedef struct AFPObj {
     gid_t *groups;
     int ngroups;
     int afp_version;
+    int cnx_cnt, cnx_max;
     /* Functions */
     void (*logout)(void);
     void (*exit)(int);
index a928d34ee38d8f23f9fd34350198d00fffc91e75..89af152b76aa6e312de2d0096002ea8283fec737 100644 (file)
@@ -65,7 +65,7 @@ int dsi_getsession(DSI *dsi, server_child_t *serv_children, int tickleval, afp_c
       LOG(log_error, logtype_dsi, "dsi_getsess: %s", strerror(errno));
       close(ipc_fds[0]);
       dsi->header.dsi_flags = DSIFL_REPLY;
-      dsi->header.dsi_data.dsi_code = DSIERR_SERVBUSY;
+      dsi->header.dsi_data.dsi_code = htonl(DSIERR_SERVBUSY);
       dsi_send(dsi);
       dsi->header.dsi_data.dsi_code = DSIERR_OK;
       kill(pid, SIGKILL);
@@ -75,16 +75,9 @@ int dsi_getsession(DSI *dsi, server_child_t *serv_children, int tickleval, afp_c
     return 0;
   }
   
-  /* child: check number of open connections. this is one off the
-   * actual count. */
-  if ((serv_children->servch_count >= serv_children->servch_nsessions) &&
-      (dsi->header.dsi_command == DSIFUNC_OPEN)) {
-    LOG(log_info, logtype_dsi, "dsi_getsess: too many connections");
-    dsi->header.dsi_flags = DSIFL_REPLY;
-    dsi->header.dsi_data.dsi_code = DSIERR_TOOMANY;
-    dsi_send(dsi);
-    exit(EXITERR_CLNT);
-  }
+  /* Save number of existing and maximum connections */
+  dsi->AFPobj->cnx_cnt = serv_children->servch_count;
+  dsi->AFPobj->cnx_max = serv_children->servch_nsessions;
 
   /* get rid of some stuff */
   dsi->AFPobj->ipc_fd = ipc_fds[1];