X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=innduct.git;a=blobdiff_plain;f=innduct.h;h=231524d04b0fdaaa54d5687fe10d474a66f71904;hp=1033ac79875ec2c54fc4d17f780e81e4d790897a;hb=HEAD;hpb=f4aee95c41a0d6231d115386b8fbb23f6b8e349a diff --git a/innduct.h b/innduct.h index 1033ac7..c85d057 100644 --- a/innduct.h +++ b/innduct.h @@ -2,25 +2,9 @@ * innduct * tailing reliable realtime streaming feeder for inn * - * Copyright (C) 2010 Ian Jackson - * - * 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 . - * - * (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.) + * Copyright Ian Jackson + * and contributors; see LICENCE.txt. + * SPDX-License-Identifier: GPL-3.0-or-later */ #ifndef INNDUCT_H @@ -59,6 +43,7 @@ #include #include #include +#include #include #include @@ -71,7 +56,7 @@ #define INNDCOMMCHILD_ESTATUS_FAIL 26 #define INNDCOMMCHILD_ESTATUS_NONESUCH 27 -#define MAX_LINE_FEEDFILE (NNTP_MSGID_MAXLEN + sizeof(TOKEN)*2 + 10) +#define MAX_LINE_FEEDFILE (NNTP_MAXLEN_MSGID + sizeof(TOKEN)*2 + 10) #define MAX_CLI_COMMAND 1000 #define VA va_list al; va_start(al,fmt) @@ -84,8 +69,10 @@ #define DUMPV(fmt,pfx,v) fprintf(f, " " #v "=" fmt, pfx v); -#define FOR_CONN(conn) \ - for ((conn)=LIST_HEAD(conns); (conn); (conn)=LIST_NEXT((conn))) +#define FOR_LIST_NODE(nodevar, list) \ + for ((nodevar)=LIST_HEAD(list); (nodevar); (nodevar)=LIST_NEXT((nodevar))) + +#define FOR_CONN(conn) FOR_LIST_NODE(conn, conns) /*----- doubly linked lists -----*/ @@ -155,47 +142,36 @@ DEFLIST(Article); /*----- configuration options -----*/ -/* when changing defaults, remember to update the manpage */ -static const char *sitename, *remote_host; -static const char *feedfile, *path_run, *path_cli, *path_cli_dir; -static int quiet_multiple=0; -static int interactive=0, try_filemon=1; -static int try_stream=1; -static int port=119; -static const char *inndconffile; +extern const char *sitename, *remote_host; +extern const char *feedfile, *path_run, *path_cli, *path_cli_dir; +extern int quiet_multiple, interactive, try_filemon, try_stream, port; +extern const char *inndconffile; -static int max_connections=10; -static int max_queue_per_conn=200; -static int target_max_feedfile_size=100000; -static int period_seconds=30; -static int filepoll_seconds=5; -static int max_queue_per_ipf=-1; +extern int max_connections, max_queue_per_conn, target_max_feedfile_size; +extern int period_seconds, filepoll_seconds, max_queue_per_ipf; +extern int connection_setup_timeout, inndcomm_flush_timeout; -static int connection_setup_timeout=200; -static int inndcomm_flush_timeout=100; - -static double nocheck_thresh= 95.0; /* converted from percentage by main */ -static double nocheck_decay= 100; /* conv'd from articles to lambda by main */ +extern double nocheck_thresh; +extern double nocheck_decay; /* all these are initialised to seconds, and converted to periods in main */ -static int reconnect_delay_periods=1000; -static int flushfail_retry_periods=1000; -static int backlog_retry_minperiods=100; -static int backlog_spontrescan_periods=300; -static int spontaneous_flush_periods=100000; -static int max_separated_periods=2000; -static int need_activity_periods=1000; -static int lowvol_thresh=3; -static int lowvol_periods=1000; +extern int reconnect_delay_periods; +extern int flushfail_retry_periods; +extern int backlog_retry_minperiods; +extern int backlog_spontrescan_periods; +extern int spontaneous_flush_periods; +extern int max_separated_periods; +extern int need_activity_periods; +extern int stats_log_periods; +extern int lowvol_thresh; +extern int lowvol_periods; -static double max_bad_data_ratio= 1; /* conv'd from percentage by main */ -static int max_bad_data_initial= 30; - /* in one corrupt 4096-byte block the number of newlines has - * mean 16 and standard deviation 3.99. 30 corresponds to z=+3.5 */ +extern double max_bad_data_ratio; +extern int max_bad_data_initial; -/*----- statistics -----*/ +/*----- article states, and statistics -----*/ typedef enum { /* in queue in conn->sent */ art_Unchecked, /* not checked, not sent checking */ @@ -203,9 +179,7 @@ typedef enum { /* in queue in conn->sent */ art_Unsolicited, /* - sent body without check */ art_MaxState, } ArtState; - -static const char *const artstate_names[]= - { "Unchecked", "Wanted", "Unsolicited", 0 }; +extern const char *const artstate_names[]; /* xmit.c */ #define RESULT_COUNTS(RCS,RCN) \ RCS(sent) \ @@ -231,6 +205,10 @@ typedef enum { RCI_max } ResultCountIndex; +typedef enum { + read_ok, read_blank, read_err, nooffer_missing, + ECI_max +} EventCountIndex; /*----- transmission buffers -----*/ @@ -250,6 +228,11 @@ struct XmitDetails { /*----- core operational data structure types -----*/ +typedef struct { + int results[art_MaxState][RCI_max]; + int events[ECI_max]; +} Counts; + struct InputFile { /* This is also an instance of struct oop_readable */ struct oop_readable readable; /* first */ @@ -267,8 +250,7 @@ struct InputFile { long inprogress; /* includes queue.count and also articles in conns */ long autodefer; /* -1 means not doing autodefer */ - int counts[art_MaxState][RCI_max]; - int readcount_ok, readcount_blank, readcount_err, count_nooffer_missing; + Counts counts; char path[]; }; @@ -283,6 +265,22 @@ struct Article { char messageid[1]; }; +struct Conn { + ISNODE(Conn); + int fd; /* may be 0, meaning closed (during construction/destruction) */ + oop_read *rd; /* likewise */ + int oopwriting; /* since on_fd is not idempotent */ + int max_queue, stream; + const char *quitting; + int since_activity; /* periods */ + ArticleList waiting; /* not yet told peer */ + ArticleList priority; /* peer says send it now */ + ArticleList sent; /* offered/transmitted - in xmit or waiting reply */ + struct iovec xmit[CONNIOVS]; + XmitDetails xmitd[CONNIOVS]; + int xmitu; +}; + #define SMS_LIST(X) \ X(NORMAL) \ X(FLUSHING) \ @@ -302,23 +300,24 @@ extern const char *sms_names[]; /*----- help.c -----*/ -static void syscrash(const char *fmt, ...) NORET_PRINTF(1,2); -static void crash(const char *fmt, ...) NORET_PRINTF(1,2); -static void info(const char *fmt, ...) PRINTF(1,2); -static void dbg(const char *fmt, ...) PRINTF(1,2); +void syscrash(const char *fmt, ...) NORET_PRINTF(1,2); +void crash(const char *fmt, ...) NORET_PRINTF(1,2); +void info(const char *fmt, ...) PRINTF(1,2); +void dbg(const char *fmt, ...) PRINTF(1,2); void logv(int sysloglevel, const char *pfx, int errnoval, - const char *fmt, va_list al) PRINTF(5,0); + const char *fmt, va_list al) PRINTF(4,0); -char *xvasprintf(const char *fmt, va_list al) PRINTF(1,0); -char *xasprintf(const char *fmt, ...) PRINTF(1,2); +char *mvasprintf(const char *fmt, va_list al) PRINTF(1,0); +char *masprintf(const char *fmt, ...) PRINTF(1,2); int close_perhaps(int *fd); void xclose(int fd, const char *what, const char *what2); void xclose_perhaps(int *fd, const char *what, const char *what2); -pid_t xfork(const char *what); +pid_t xfork(const char *what); /* also runs postfork in child */ +pid_t xfork_bare(const char *what); -static void on_fd_read_except(int fd, oop_call_fd callback); +void on_fd_read_except(int fd, oop_call_fd callback); void cancel_fd_read_except(int fd); void report_child_status(const char *what, int status); @@ -329,6 +328,7 @@ void xunlink(const char *path, const char *what); time_t xtime(void); void xsigaction(int signo, const struct sigaction *sa); void xsigsetdefault(int signo); +void raise_default(int signo) NORET; void xgettimeofday(struct timeval *tv_r); void xsetnonblock(int fd, int nonb); @@ -349,38 +349,132 @@ static inline int isewouldblock(int errnoval) { return errnoval==EWOULDBLOCK || errnoval==EAGAIN; } -/*----- innduct.c -----*/ +#define INNLOGSETS(INNLOGSET) \ + INNLOGSET(die, "fatal", LOG_ERR) \ + INNLOGSET(warn, "warning", LOG_WARNING) \ + INNLOGSET(notice, "notice", LOG_NOTICE) \ + INNLOGSET(debug, "debug", LOG_DEBUG) +#define INNLOGSET_DECLARE(fn, pfx, sysloglevel) \ + void duct_log_##fn(int l, const char *fmt, va_list al, int errval) \ + PRINTF(2,0); +INNLOGSETS(INNLOGSET_DECLARE) + +/*----- duct.c -----*/ void postfork(void); +void period(void); + +/*----- cli.c -----*/ + +void cli_init(void); +void cli_stdio(void); /*----- conn.c -----*/ void conn_closefd(Conn *conn, const char *msgprefix); +void check_idle_conns(void); +int conn_busy(Conn *conn); +void conn_dispose(Conn *conn); + +void vconnfail(Conn *conn, const char *fmt, va_list al) PRINTF(2,0); +void connfail(Conn *conn, const char *fmt, ...) PRINTF(2,3); + +void notice_conns_more(const char *new_kind); +void notice_conns_fewer(void); +void notice_conns_stats(void); + +int allow_connect_start(void); +void connect_start(void); /*----- defer.c -----*/ void poll_backlog_file(void); +void search_backlog_file(void); +void open_defer(void); +void close_defer(void); + +/*----- filemon.c -----*/ + +int filemon_method_init(void); +void filemon_method_dump_info(FILE *f); + +void filemon_start(InputFile *ipf); +void filemon_stop(InputFile *ipf); /*----- infile.c -----*/ void filepoll(void); +void inputfile_reading_start(InputFile *ipf); +void inputfile_reading_stop(InputFile *ipf); +void inputfile_reading_pause(InputFile *ipf); +void inputfile_reading_resume(InputFile *ipf); + /* pause and resume are idempotent, and no-op if not done _reading_start */ + +InputFile *open_input_file(const char *path); +void close_input_file(InputFile *ipf); /* does not free */ +char *dbg_report_ipf(InputFile *ipf); + +void tailing_make_readable(InputFile *ipf); + +/*----- recv.c -----*/ + +extern const oop_rd_style peer_rd_style; +oop_rd_call peer_rd_ok, peer_rd_err; + +void article_done(Article *art, int whichcount); + /*----- statemc.c -----*/ -sig_atomic_t terminate_sig_flag; +void statemc_check_flushing_done(void); +void statemc_check_backlog_done(void); + +extern sig_atomic_t terminate_sig_flag; +void statemc_period_poll(void); +void statemc_lock(void); +void init_signals(void); +void statemc_init(void); +void showstats(void); + +#define SMS(newstate, periods, why) \ + (statemc_setstate(sm_##newstate,(periods),#newstate,(why))) +void statemc_setstate(StateMachineState newsms, int periods, + const char *forlog, const char *why); + +void statemc_start_flush(const char *why); /* Normal => Flushing */ +void spawn_inndcomm_flush(const char *why); /* Moved => Flushing */ +int trigger_flush_ok(const char *why /* 0 means timeout */); + /* => Flushing,FLUSHING, ret 1; or ret 0 */ + +void preterminate(void); /*----- xmit.c -----*/ void inputfile_queue_check_expired(InputFile *ipf); +void check_assign_articles(void); +void queue_check_input_done(void); +void check_reading_pause_resume(InputFile *ipf); + +void conn_maybe_write(Conn *conn); +void conn_make_some_xmits(Conn *conn); +void *conn_write_some_xmits(Conn *conn); + +void xmit_free(XmitDetails *d); + +int article_check_expired(Article *art /* must be queued, not conn */); +void article_autodefer(InputFile *ipf, Article *art); +void article_defer(Article *art /* not on a queue */, int whichcount); +void autodefer_input_file(InputFile *ipf); /*----- external linkage for debug/dump only -----*/ -pid_t connecting_child; -pid_t inndcomm_child; +extern pid_t connecting_child; +extern int connecting_fdpass_sock; +extern pid_t inndcomm_child; /*========== general operational variables ==========*/ -/* innduct.c */ +/* duct.c */ extern oop_source *loop; extern ConnList conns; extern char *path_lock, *path_flushing, *path_defer, *path_dump; @@ -389,11 +483,14 @@ extern pid_t self_pid; extern int *lowvol_perperiod; extern int lowvol_circptr; extern int lowvol_total; /* does not include current period */ +extern int until_stats_log; /* statemc.c */ extern StateMachineState sms; extern int until_flush; extern InputFile *main_input_file, *flushing_input_file, *backlog_input_file; +extern Counts backlog_counts; +extern int backlog_counts_report; extern FILE *defer; extern int until_connect, until_backlog_nextscan; extern double accept_proportion;