]> git.lizzy.rs Git - dragonnet.git/blob - peer.c
9a6d57b318339d074c81ceaec37422470c60c78c
[dragonnet.git] / peer.c
1 #include <assert.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4
5 #include "peer.h"
6
7 DragonnetPeer *dragonnet_connect(char *addr)
8 {
9         DragonnetPeer *p = malloc(sizeof *p);
10         p->mu = malloc(sizeof *p->mu);
11         pthread_rwlock_init(p->mu, NULL);
12         pthread_rwlock_wrlock(p->mu);
13
14         p->sock = socket(AF_INET6, SOCK_STREAM, 0);
15         p->raddr = dragonnet_addr_parse_str(addr);
16
17         struct sockaddr_in6 sock_addr = dragonnet_addr_sock(p->raddr);
18         if (connect(p->sock, (const struct sockaddr *) &sock_addr, sizeof sock_addr) < 0) {
19                 perror("connect");
20                 dragonnet_peer_delete(p);
21                 return NULL;
22         }
23
24         struct sockaddr_in6 sock_name;
25         socklen_t sock_namelen = sizeof sock_name;
26
27         if (getsockname(p->sock, (struct sockaddr *) &sock_name, &sock_namelen) < 0) {
28                 perror("getsockname");
29                 dragonnet_peer_delete(p);
30                 return NULL;
31         }
32
33         p->laddr = dragonnet_addr_parse_sock(sock_name);
34
35         pthread_rwlock_unlock(p->mu);
36         return p;
37 }
38
39 void dragonnet_peer_close(DragonnetPeer *p)
40 {
41         pthread_rwlock_wrlock(p->mu);
42
43         assert(p->state == DRAGONNET_PEER_ACTIVE);
44         shutdown(p->sock, SHUT_RDWR);
45         p->state++;
46
47         pthread_rwlock_unlock(p->mu);
48 }
49
50 void dragonnet_peer_delete(DragonnetPeer *p)
51 {
52         pthread_rwlock_destroy(p->mu);
53         free(p);
54 }