summaryrefslogtreecommitdiffstats
path: root/src/tcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tcp.c')
-rw-r--r--src/tcp.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/src/tcp.c b/src/tcp.c
new file mode 100644
index 0000000..99f8828
--- /dev/null
+++ b/src/tcp.c
@@ -0,0 +1,62 @@
+void disconnection (struct torrent * t) {
+ fprintf(stderr, "disconnecting from peer ");
+ peer_print(stderr, t->dl);
+ fprintf(stderr, " nfds=%ld, pollfds=%zu\n", *t->dht->nfds, *t->dht->pollfds_size);
+ for (size_t i = 0; i < *t->dht->nfds; i++) {
+ if ((*t->dht->pollfds)[i].fd == t->socket) {
+ if (i != (*t->dht->nfds)--)
+ (*t->dht->pollfds)[i] = (*t->dht->pollfds)[*t->dht->nfds];
+ break;
+ }
+ }
+ if (t->dl->flags & goodmeta) {
+ char buf[128];
+ bin2hex(buf, t->hash, 20);
+ strcpy(buf+40, ".torrent");
+ FILE * f = fopen(buf, "w+b");
+ if (!f) {
+ L(user, t->dht, "fopen(%s, \"w+b\"): %s", buf, strerror(errno));
+ return;
+ }
+ char remote[INET6_ADDRSTRLEN + 64];
+ if (!inet_ntop(t->dl->addr.sin6_family, t->dl->addr.sin6_addr.s6_addr, remote, INET6_ADDRSTRLEN+7))
+ snprintf(remote, sizeof remote, "(inet_ntop: %s)", strerror(errno));
+ sprintf(remote+strlen(remote), "/%d", ntohs(t->dl->addr.sin6_port));
+ fprintf(f, "d10:created by58:http://ni.šijanec.eu/sijanec/travnik mailto:tk@sijanec.eu13:creation datei%lde8:encoding5:UTF-84:info", time(NULL));
+ fwrite(t->metadata, 1, t->size, f); // i don't expect any errors here
+ fprintf(f, "6:sourced2:ip%zu:%s", strlen(remote), remote);
+ if (t->software)
+ fprintf(f, "1:v%zu:%s", strlen(t->software), t->software);
+ fputs("ee", f);
+ if (fclose(f) == EOF)
+ L(user, t->dht, "fclose(%s): %s", buf, strerror(errno));
+ }
+#ifdef DISCONNECTION_MIXIN_BOTTOM
+ DISCONNECTION_MIXIN_BOTTOM
+#endif
+}
+void intentions (struct torrent * t) {
+ for (size_t i = 0; i < *t->dht->nfds; i++)
+ if ((*t->dht->pollfds)[i].fd == t->socket) {
+ (*t->dht->pollfds)[i].events &= ~(POLLIN | POLLOUT);
+ if (t->state & incoming)
+ (*t->dht->pollfds)[i].events |= POLLIN;
+ if (t->state & outgoing)
+ (*t->dht->pollfds)[i].events |= POLLOUT;
+ }
+ fprintf(stderr, "peer's intentions: ");
+ peer_print(stderr, t->dl);
+ fprintf(stderr, " nfds=%ld, pollfds=%zu%s%s\n", *t->dht->nfds, *t->dht->pollfds_size, (t->state & incoming) ? " reading" : "", (t->state & outgoing) ? " writing" : "");
+}
+void connection (struct dht * d, struct torrent * t) {
+ if (*d->pollfds_size <= *d->nfds)
+ *d->pollfds = reallocarray(*d->pollfds, (*d->pollfds_size *= 2), sizeof **d->pollfds);
+ (*d->pollfds)[*d->nfds].events = POLLIN | POLLOUT;
+ (*d->pollfds)[(*d->nfds)++].fd = t->socket;
+ fprintf(stderr, "attempting to connect to peer ");
+ peer_print(stderr, t->dl);
+ fprintf(stderr, " nfds=%ld, pollfds=%zu\n", *d->nfds, *d->pollfds_size);
+ t->disconnection = disconnection;
+ t->dht = d;
+ t->intentions = intentions;
+}