7 DragonnetPeer *dragonnet_connect(char *addr)
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);
14 p->sock = socket(AF_INET6, SOCK_STREAM, 0);
15 p->raddr = dragonnet_addr_parse_str(addr);
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) {
20 dragonnet_peer_delete(p);
24 struct sockaddr_in6 sock_name;
25 socklen_t sock_namelen = sizeof sock_name;
27 if (getsockname(p->sock, (struct sockaddr *) &sock_name, &sock_namelen) < 0) {
28 perror("getsockname");
29 dragonnet_peer_delete(p);
33 p->laddr = dragonnet_addr_parse_sock(sock_name);
35 pthread_rwlock_unlock(p->mu);
39 void dragonnet_peer_close(DragonnetPeer *p)
41 pthread_rwlock_wrlock(p->mu);
43 assert(p->state == DRAGONNET_PEER_ACTIVE);
44 shutdown(p->sock, SHUT_RDWR);
47 pthread_rwlock_unlock(p->mu);
50 void dragonnet_peer_delete(DragonnetPeer *p)
52 pthread_rwlock_destroy(p->mu);