summaryrefslogtreecommitdiffstats
path: root/src/tcp.c
blob: bfd49bcfdb0d16766038df83fb931ed4c1e8c708 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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, "tcp 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;
}