tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

commit 61976a4b1ca5dc9c7f9494ee3bf17a96c1182cf0
parent 482437754a7a30b651f096d4432a42aa61bd3b17
Author: Taylor Yu <catalyst@torproject.org>
Date:   Tue,  9 Apr 2019 12:22:31 -0500

Factor out control reply output

Create a set of abstractions for controller commands and events to
output replies to the control channel.  The control protocol has a
relatively consistent SMTP-like structure, so it's helpful when code
that implements control commands and events doesn't explicitly format
everything on its own.

Diffstat:
Msrc/feature/control/control_proto.c | 106+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/feature/control/control_proto.h | 24++++++++++++++++++++++++
2 files changed, 130 insertions(+), 0 deletions(-)

diff --git a/src/feature/control/control_proto.c b/src/feature/control/control_proto.c @@ -168,3 +168,109 @@ send_control_done(control_connection_t *conn) { connection_write_str_to_buf("250 OK\r\n", conn); } + +/** Write a reply to the control channel. + * + * @param conn control connection + * @param code numeric result code + * @param c separator character, usually ' ', '-', or '+' + * @param s string + */ +void +control_write_reply(control_connection_t *conn, int code, int c, const char *s) +{ + connection_printf_to_buf(conn, "%03d%c%s\r\n", code, c, s); +} + +/** Write a formatted reply to the control channel. + * + * @param conn control connection + * @param code numeric result code + * @param c separator character, usually ' ', '-', or '+' + * @param fmt format string + * @param ap va_list from caller + */ +void +control_vprintf_reply(control_connection_t *conn, int code, int c, + const char *fmt, va_list ap) +{ + char *buf = NULL; + int len; + + len = tor_vasprintf(&buf, fmt, ap); + if (len < 0) { + log_err(LD_BUG, "Unable to format string for controller."); + tor_assert(0); + } + control_write_reply(conn, code, c, buf); + tor_free(buf); +} + +/** Write an EndReplyLine */ +void +control_write_endreply(control_connection_t *conn, int code, const char *s) +{ + control_write_reply(conn, code, ' ', s); +} + +/** Write a formatted EndReplyLine */ +void +control_printf_endreply(control_connection_t *conn, int code, + const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + control_vprintf_reply(conn, code, ' ', fmt, ap); + va_end(ap); +} + +/** Write a MidReplyLine */ +void +control_write_midreply(control_connection_t *conn, int code, const char *s) +{ + control_write_reply(conn, code, '-', s); +} + +/** Write a formatted MidReplyLine */ +void +control_printf_midreply(control_connection_t *conn, int code, const char *fmt, + ...) +{ + va_list ap; + + va_start(ap, fmt); + control_vprintf_reply(conn, code, '-', fmt, ap); + va_end(ap); +} + +/** Write a DataReplyLine */ +void +control_write_datareply(control_connection_t *conn, int code, const char *s) +{ + control_write_reply(conn, code, '+', s); +} + +/** Write a formatted DataReplyLine */ +void +control_printf_datareply(control_connection_t *conn, int code, const char *fmt, + ...) +{ + va_list ap; + + va_start(ap, fmt); + control_vprintf_reply(conn, code, '+', fmt, ap); + va_end(ap); +} + +/** Write a CmdData */ +void +control_write_data(control_connection_t *conn, const char *data) +{ + char *esc = NULL; + size_t esc_len; + + esc_len = write_escaped_data(data, strlen(data), &esc); + connection_buf_add(esc, esc_len, TO_CONN(conn)); + tor_free(esc); +} diff --git a/src/feature/control/control_proto.h b/src/feature/control/control_proto.h @@ -21,4 +21,28 @@ size_t write_escaped_data(const char *data, size_t len, char **out); size_t read_escaped_data(const char *data, size_t len, char **out); void send_control_done(control_connection_t *conn); +void control_write_reply(control_connection_t *conn, int code, int c, + const char *s); +void control_vprintf_reply(control_connection_t *conn, int code, int c, + const char *fmt, va_list ap) + CHECK_PRINTF(4, 0); +void control_write_endreply(control_connection_t *conn, int code, + const char *s); +void control_printf_endreply(control_connection_t *conn, int code, + const char *fmt, ...) + CHECK_PRINTF(3, 4); +void control_write_midreply(control_connection_t *conn, int code, + const char *s); +void control_printf_midreply(control_connection_t *conn, int code, + const char *fmt, + ...) + CHECK_PRINTF(3, 4); +void control_write_datareply(control_connection_t *conn, int code, + const char *s); +void control_printf_datareply(control_connection_t *conn, int code, + const char *fmt, + ...) + CHECK_PRINTF(3, 4); +void control_write_data(control_connection_t *conn, const char *data); + #endif /* !defined(TOR_CONTROL_PROTO_H) */