7 #include "recv_thread.h"
9 const struct timeval dragonnet_timeout = {
14 static bool dragonnet_peer_init(DragonnetPeer *p, char *addr)
16 pthread_rwlock_init(&p->mu, NULL);
17 pthread_rwlock_wrlock(&p->mu);
19 p->sock = socket(AF_INET6, SOCK_STREAM, 0);
20 p->raddr = dragonnet_addr_parse_str(addr);
22 if (setsockopt(p->sock, SOL_SOCKET, SO_RCVTIMEO, &dragonnet_timeout,
23 sizeof dragonnet_timeout) < 0) {
28 if (setsockopt(p->sock, SOL_SOCKET, SO_SNDTIMEO, &dragonnet_timeout,
29 sizeof dragonnet_timeout) < 0) {
34 struct sockaddr_in6 sock_addr = dragonnet_addr_sock(p->raddr);
35 if (connect(p->sock, (const struct sockaddr *) &sock_addr,
36 sizeof sock_addr) < 0) {
41 struct sockaddr_in6 sock_name;
42 socklen_t sock_namelen = sizeof sock_name;
44 if (getsockname(p->sock, (struct sockaddr *) &sock_name, &sock_namelen) < 0) {
45 perror("getsockname");
49 p->laddr = dragonnet_addr_parse_sock(sock_name);
51 pthread_rwlock_unlock(&p->mu);
55 DragonnetPeer *dragonnet_connect(char *addr)
57 DragonnetPeer *p = malloc(sizeof *p);
58 if (!dragonnet_peer_init(p, addr)) {
59 dragonnet_peer_delete(p);
66 void dragonnet_peer_run(DragonnetPeer *p)
68 pthread_t recv_thread;
69 pthread_create(&recv_thread, NULL, &dragonnet_peer_recv_thread, p);
70 pthread_join(recv_thread, NULL);
73 void dragonnet_peer_close(DragonnetPeer *p)
75 pthread_rwlock_wrlock(&p->mu);
77 if (p->state == DRAGONNET_PEER_ACTIVE) {
78 shutdown(p->sock, SHUT_RDWR);
82 pthread_rwlock_unlock(&p->mu);
85 void dragonnet_peer_delete(DragonnetPeer *p)
87 pthread_rwlock_destroy(&p->mu);