commit d040472e70970fdbbabaee795dacb328a439b650
parent d6db399d7593abedb6569d335a7f337c32b25e42
Author: Mario Rosell R. Martinez <mario@mariorosell.es>
Date: Thu, 19 Mar 2026 21:40:44 +0100
Buffer reads
One syscall per byte read was a lot, and more with TLS :). Now it buffers 4kb,
or whatever ANNTP_BUFSIZE is.
Diffstat:
2 files changed, 43 insertions(+), 8 deletions(-)
diff --git a/.anntp.h.swo b/.anntp.h.swo
Binary files differ.
diff --git a/anntp.h b/anntp.h
@@ -68,6 +68,7 @@ struct anntp_connection {
struct hostent* host_he; /* resolved host entry */
struct in_addr addr; /* resolved IP address */
uchar_t read_buffer[ANNTP_BUFSIZE]; /* read buffer */
+ size_t read_pos; /* used for buffering */
size_t read_len; /* length of data in buffer */
#ifdef ANNTP_TLS
SSL* ssl; /* TLS session */
@@ -80,7 +81,7 @@ typedef int (*AnntpLineCb)(const char* line, void* extra);
/*** function declarations ***/
-ANNTP_API void anntp_init(void);
+ANNTP_API void anntp_init(void);
ANNTP_API AnntpConnection* anntp_mkconn(const char* host, const char* port, Bool tls);
ANNTP_API void anntp_freeconn(AnntpConnection* conn);
ANNTP_API ssize_t anntp_read(AnntpConnection* conn, uchar_t* buf, size_t bufsize);
@@ -96,6 +97,8 @@ ANNTP_API int anntp_auth(AnntpConnection* conn, const char* login, c
#ifdef ANNTP_IMPLEMENTATION
+static ssize_t _afillbuf(AnntpConnection* c);
+
void
anntp_init(void)
{
@@ -117,6 +120,7 @@ anntp_mkconn(const char* host, const char* port, Bool tls)
cv->host = strdup(host);
cv->use_tls = tls;
cv->state = ANS_OFF;
+ cv->fd = -1;
/* create socket */
cv->fd = socket(AF_INET, SOCK_STREAM, 0);
@@ -244,16 +248,22 @@ anntp_readline(AnntpConnection* cv, char* buf, size_t maxlen)
if (!cv || !buf || maxlen == 0) return -1;
size_t pos = 0;
+
while (pos < maxlen - 1) {
- uchar_t c;
- ssize_t n = anntp_read(cv, &c, 1);
- if (n <= 0) {
- if (pos == 0) return n;
- break;
+ /* refill buffer if empty */
+ if (cv->read_pos >= cv->read_len) {
+ ssize_t n = _afillbuf(cv);
+ if (n <= 0) {
+ if (pos == 0) return n;
+ break;
+ }
}
- buf[pos++] = c;
- if (c == '\n') break;
+ char ch = (char)cv->read_buffer[cv->read_pos++];
+ buf[pos++] = ch;
+
+ if (ch == '\n')
+ break;
}
buf[pos] = '\0';
@@ -336,6 +346,8 @@ anntp_readdot_cb(AnntpConnection* cv, AnntpLineCb cb, void* extra)
if (cb(out, extra) != 0)
return 1; /* user aborted */
}
+
+ return 0;
}
/* NOTE: I have a gut feeling this auth mechanism is probably a bit insecure... */
@@ -402,5 +414,28 @@ anntp_auth(AnntpConnection* cv, const char* user, const char* pass)
return -1;
}
+/* fill read buffer with data */
+static ssize_t
+_afillbuf(AnntpConnection* c)
+{
+ ssize_t n;
+
+#ifdef ANNTP_TLS
+ if (c->use_tls && c->ssl)
+ n = SSL_read(c->ssl, c->read_buffer, ANNTP_BUFSIZE);
+ else
+#endif
+ n = read(c->fd, c->read_buffer, ANNTP_BUFSIZE);
+
+ if (n > 0) {
+ c->read_len = (size_t)n;
+ c->read_pos = 0;
+ } else {
+ c->read_len = 0;
+ }
+
+ return n;
+}
+
#endif /* ANNTP_IMPLEMENTATION */