diff options
author | Anton Luka Šijanec <anton@sijanec.eu> | 2022-11-21 22:13:04 +0100 |
---|---|---|
committer | Anton Luka Šijanec <anton@sijanec.eu> | 2022-11-21 22:13:04 +0100 |
commit | a36d9a1b09a6632fd66ad67c7ba0c9692b058608 (patch) | |
tree | f8c4bb98ed1dfa04d983035a4299166eba774342 /src | |
parent | created utils/bencoding.c, fixed bencoding (for now decode only). TODO: fuzz (diff) | |
download | travnik-a36d9a1b09a6632fd66ad67c7ba0c9692b058608.tar travnik-a36d9a1b09a6632fd66ad67c7ba0c9692b058608.tar.gz travnik-a36d9a1b09a6632fd66ad67c7ba0c9692b058608.tar.bz2 travnik-a36d9a1b09a6632fd66ad67c7ba0c9692b058608.tar.lz travnik-a36d9a1b09a6632fd66ad67c7ba0c9692b058608.tar.xz travnik-a36d9a1b09a6632fd66ad67c7ba0c9692b058608.tar.zst travnik-a36d9a1b09a6632fd66ad67c7ba0c9692b058608.zip |
Diffstat (limited to '')
-rw-r--r-- | src/bencoding.c | 65 | ||||
-rw-r--r-- | src/dht.c | 14 |
2 files changed, 73 insertions, 6 deletions
diff --git a/src/bencoding.c b/src/bencoding.c index d1324c7..d1ac517 100644 --- a/src/bencoding.c +++ b/src/bencoding.c @@ -21,11 +21,12 @@ struct bencoding { struct bencoding * next; /**< NULL if element is not member of a list or dict */ struct bencoding * prev; struct bencoding * child; /**< NULL if element is not a list or dict or if it has 0 children */ + struct bencoding * parent; enum benc type; /**< type | opts of this element */ struct bencoding * key; /**< the key element, string according to the spec, applicable for dict */ char * value; /**< set to the content of the element, value is not null terminated unless terminate opt is set. NULL for dict and list. */ size_t valuelen; /**< length of string value, as value is not null terminated, internal value for list or dict. */ - int intvalue; + long int intvalue; int index; char oldterminator; /**< when opts&terminate, the character that was replaced with \0 is stored here */ char oldterminatorls; /**< when opts&terminate when there was no more space, replaced character is stored here. @@ -60,7 +61,7 @@ void free_bencoding (struct bencoding * b) { * @param a [in] the character in question */ -int b2json_charsize (char a) { +int b2json_charsize (unsigned char a) { if (a == '"') return 2; if (a == '\\') @@ -88,7 +89,7 @@ int b2json_charsize (char a) { * @return the destination pointer, incremented for the number of bytes written */ -char * b2json_charrepr (char * dest, char a) { +char * b2json_charrepr (char * dest, unsigned char a) { switch (a) { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstringop-truncation" @@ -147,7 +148,7 @@ int b2json_length (struct bencoding * b) { } if (b->type & num) { char buf[512]; - sprintf(buf, "%d", b->intvalue); + sprintf(buf, "%ld", b->intvalue); return strlen(buf); } if (b->type & list) { @@ -204,7 +205,7 @@ char * b2json (char * dest, struct bencoding * b) { } if (b->type & num) { char buf[512]; - sprintf(buf, "%d", b->intvalue); + sprintf(buf, "%ld", b->intvalue); strncpy(dest, buf, strlen(buf)); return dest+strlen(buf); } @@ -318,6 +319,8 @@ struct bencoding * bdecode (char * s, int len, enum benc opts) { if (oldarbeit && oldarbeit->type & string && oldarbeit->type & terminate && oldarbeit->oldterminator) c[0] = oldarbeit->oldterminator; arbeit = bdecode(c, len == -1 ? -1 : len-(c-s), opts); + if (arbeit) + arbeit->parent = b; if (oldarbeit && oldarbeit->type & string && oldarbeit->type & terminate && oldarbeit->oldterminator) c[0] = '\0'; if (!arbeit) /* bdecoding failed or last element */ @@ -362,6 +365,7 @@ struct bencoding * bdecode (char * s, int len, enum benc opts) { return NULL; default: if (!(s[0] >= '0' && s[0] <= '9')) { /* not a string. not checking this would allow DoS for parsing "lx" */ + fprintf(stderr, "bencoding: unknown type %c\n", s[0]); free(b); return NULL; } @@ -389,6 +393,55 @@ struct bencoding * bdecode (char * s, int len, enum benc opts) { /** * returns a pointer to bencoding struct matching bencoding path or NULL if not found + * + * path key/key2/key3 will given object {"key":{"key2":{"key3":val}}} return val * - * [xxx] specifies xxxth child of a dict or list. if + * @param benc [in] the bencoding dict to look in + * @param key [in] the path */ + +struct bencoding * bpath (struct bencoding * benc, const char * key) { + if (!benc) + return NULL; + if (!benc->child) + return NULL; + benc = benc->child; + if (key[0] == '/') + key++; + size_t len = strlen(key); + char * c = strchr(key, '/'); + if (c) + len = c - key; + while (benc) { + if (benc->key && benc->key->type & num) { + char buf[512]; + sprintf(buf, "%ld", strtol(key, NULL, 10)); + if (!strncmp(buf, key, len) && benc->key->intvalue == strtol(key, NULL, 10)) { + if (!c) + return benc; + else + return bpath(benc, key+len); + } + } + if (benc->key && benc->key->type & string) { + if (!strncmp(key, benc->key->value, MIN(benc->key->valuelen, len))) { + if (!c) + return benc; + else + return bpath(benc, key+len); + } + } + benc = benc->next; + } + return NULL; +} + +/** + * macro that loops following code body across a list or values of dict + * + * @param elem [out] name of element that will be used for value while looping + * @param list [in] list/dict of values + */ + +#define bforeach(elem, list) \ + for (struct bencoding * elem = list ? list->child : NULL; elem; elem = elem->next) diff --git a/src/dht.c b/src/dht.c new file mode 100644 index 0000000..629bf26 --- /dev/null +++ b/src/dht.c @@ -0,0 +1,14 @@ +struct dht { + char id[20]; + int socket; +}; +struct node { + char id[20]; + int lost; + int sent; + int answers; + int malformed; + int received; + time_t last; + struct sockaddr addr; +}; |