+/*
+ * innduct
+ * tailing reliable realtime streaming feeder for inn
+ * conn.c - connection establishment and teardown
+ *
+ * Copyright (C) 2010 Ian Jackson <ijackson@chiark.greenend.org.uk>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * (I believe that when you compile and link this as part of the inn2
+ * build, with the Makefile runes I have provided, all the libraries
+ * and files which end up included in innduct are licence-compatible
+ * with GPLv3. If not then please let me know. -Ian Jackson.)
+ */
+
+#include "innduct.h"
+
/*========== management of connections ==========*/
static void reconnect_blocking_event(void) {
conn->fd, msgprefix, strerror(errno));
}
-static int conn_busy(Conn *conn) {
+int conn_busy(Conn *conn) {
return
conn->waiting.count ||
conn->priority.count ||
conn->xmitu;
}
-static void conn_dispose(Conn *conn) {
+void conn_dispose(Conn *conn) {
if (!conn) return;
if (conn->rd) {
oop_rd_cancel(conn->rd);
return OOP_CONTINUE;
}
-static void vconnfail(Conn *conn, const char *fmt, va_list al) {
+void vconnfail(Conn *conn, const char *fmt, va_list al) {
int requeue[art_MaxState];
memset(requeue,0,sizeof(requeue));
LIST_REMOVE(conns,conn);
char *m= xvasprintf(fmt,al);
- warn("C%d (now %d) connection failed requeueing " RCI_TRIPLE_FMT_BASE ": %s",
+ warn("C%d (now %d) connection failed "
+ "(requeueing " RCI_TRIPLE_FMT_BASE "): %s",
conn->fd, conns.count, RCI_TRIPLE_VALS_BASE(requeue, /*nothing*/), m);
free(m);
check_assign_articles();
}
-static void connfail(Conn *conn, const char *fmt, ...) {
+void connfail(Conn *conn, const char *fmt, ...) {
va_list al;
va_start(al,fmt);
vconnfail(conn,fmt,al);
* For our last connection, we also shut it down if we have had
* less than K in the last L
*/
-static void check_idle_conns(void) {
+void check_idle_conns(void) {
Conn *conn;
int volthisperiod= lowvol_perperiod[lowvol_circptr];
conn_idle_close(conn, "low volume");
}
+/*---------- reporting numbers of connections ----------*/
+
+static int conns_max_reported, conns_idle_reported;
+
+void notice_conns_more(const char *new_kind) {
+ if (conns.count > conns_max_reported) {
+ notice("up to %d connection(s) (%s)", conns.count, new_kind);
+ conns_max_reported= conns.count;
+ }
+}
+
+void notice_conns_fewer(void) {
+ if (!conns.count && !conns_idle_reported) {
+ notice("low volume, using intermittent connection");
+ conns_idle_reported= 1;
+ }
+}
+
+void notice_conns_stats(void) {
+ notice("currently %d connection(s)", conns.count);
+ conns_max_reported= conns.count;
+ conns_idle_reported= 0;
+}
+
/*---------- making new connections ----------*/
-static pid_t connecting_child;
+pid_t connecting_child;
int connecting_fdpass_sock;
static void connect_attempt_discard(void) {
if (r) syscrash("oop_rd_read for peer (fd=%d)",conn->fd);
LIST_ADDHEAD(conns, conn);
- notice("C%d (now %d) connected %s",
- conn->fd, conns.count, conn->stream ? "streaming" : "plain");
+ const char *streamdesc= conn->stream ? "streaming" : "plain";
+ info("C%d (now %d) connected %s", conn->fd, conns.count, streamdesc);
+ notice_conns_more(streamdesc);
connect_attempt_discard();
check_assign_articles();
return OOP_CONTINUE;
}
-static int allow_connect_start(void) {
+int allow_connect_start(void) {
return conns.count < max_connections
&& !connecting_child
&& !until_connect;
}
-static void connect_start(void) {
+void connect_start(void) {
assert(!connecting_child);
assert(!connecting_fdpass_sock);