+ if((maxconnections - 10) < rb_get_fd(F)) /* XXX this is kinda bogus */
+ {
+ ++ServerStats.is_ref;
+ /*
+ * slow down the whining to opers bit
+ */
+ if((last_oper_notice + 20) <= rb_current_time())
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "All connections in use. (%s)",
+ get_listener_name(listener));
+ last_oper_notice = rb_current_time();
+ }
+
+ rb_write(F, "ERROR :All connections in use\r\n", 32);
+ rb_close(F);
+ /* Re-register a new IO request for the next accept .. */
+ return 0;
+ }
+
+ aconf = find_dline(addr, addr->sa_family);
+ if(aconf != NULL && (aconf->status & CONF_EXEMPTDLINE))
+ return 1;
+
+ /* Do an initial check we aren't connecting too fast or with too many
+ * from this IP... */
+ if(aconf != NULL)
+ {
+ ServerStats.is_ref++;
+
+ if(ConfigFileEntry.dline_with_reason)
+ {
+ if (rb_snprintf(buf, sizeof(buf), "ERROR :*** Banned: %s\r\n", aconf->passwd) >= (int)(sizeof(buf)-1))
+ {
+ buf[sizeof(buf) - 3] = '\r';
+ buf[sizeof(buf) - 2] = '\n';
+ buf[sizeof(buf) - 1] = '\0';
+ }
+ }
+ else
+ strcpy(buf, "ERROR :You have been D-lined.\r\n");
+
+ rb_write(F, buf, strlen(buf));
+ rb_close(F);
+ return 0;
+ }
+
+ if(check_reject(F, addr))
+ return 0;
+
+ if(throttle_add(addr))
+ {
+ rb_write(F, toofast, strlen(toofast));
+ rb_close(F);
+ return 0;
+ }
+
+ return 1;
+}
+
+static void
+accept_ssld(rb_fde_t *F, struct sockaddr *addr, struct sockaddr *laddr, struct Listener *listener)
+{
+ ssl_ctl_t *ctl;
+ rb_fde_t *xF[2];
+ if(rb_socketpair(AF_UNIX, SOCK_STREAM, 0, &xF[0], &xF[1], "Incoming ssld Connection") == -1)
+ {
+ ilog_error("creating SSL/TLS socket pairs");
+ rb_close(F);
+ return;
+ }
+ ctl = start_ssld_accept(F, xF[1], rb_get_fd(xF[0])); /* this will close F for us */
+ add_connection(listener, xF[0], addr, laddr, ctl);
+}
+
+static void
+accept_callback(rb_fde_t *F, int status, struct sockaddr *addr, rb_socklen_t addrlen, void *data)
+{
+ struct Listener *listener = data;
+ struct rb_sockaddr_storage lip;
+ unsigned int locallen = sizeof(struct rb_sockaddr_storage);
+
+ ServerStats.is_ac++;
+
+ if(getsockname(rb_get_fd(F), (struct sockaddr *) &lip, &locallen) < 0)
+ {
+ /* this can fail if the connection disappeared in the meantime */
+ rb_close(F);
+ return;
+ }
+
+ if(listener->ssl)
+ accept_ssld(F, addr, (struct sockaddr *)&lip, listener);
+ else
+ add_connection(listener, F, addr, (struct sockaddr *)&lip, NULL);