From: Ralph Boehme Date: Mon, 23 Sep 2013 09:27:29 +0000 (+0200) Subject: Enhance handling of connection attempts when hitting the connection limit X-Git-Url: https://arthur.barton.de/gitweb/?p=netatalk.git;a=commitdiff_plain;h=36f3e9d7b43b2d29f5c434573778e6a76dc01e8f Enhance handling of connection attempts when hitting the connection limit Bug #529. --- diff --git a/NEWS b/NEWS index cde45f14..6416a89a 100644 --- 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 ================ diff --git a/etc/afpd/auth.c b/etc/afpd/auth.c index bec624dc..ed08bbfa 100644 --- a/etc/afpd/auth.c +++ b/etc/afpd/auth.c @@ -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); diff --git a/include/atalk/afp.h b/include/atalk/afp.h index 76315aa4..0c2489ea 100644 --- a/include/atalk/afp.h +++ b/include/atalk/afp.h @@ -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 */ diff --git a/include/atalk/globals.h b/include/atalk/globals.h index 61cf247f..e1b5454b 100644 --- a/include/atalk/globals.h +++ b/include/atalk/globals.h @@ -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); diff --git a/libatalk/dsi/dsi_getsess.c b/libatalk/dsi/dsi_getsess.c index a928d34e..89af152b 100644 --- a/libatalk/dsi/dsi_getsess.c +++ b/libatalk/dsi/dsi_getsess.c @@ -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];