6 #include "recv_thread.h"
8 const struct timeval dragonnet_timeout = {
13 DragonnetPeer *dragonnet_connect(char *addr)
15 DragonnetPeer *p = malloc(sizeof *p);
16 p->mu = malloc(sizeof *p->mu);
17 pthread_rwlock_init(p->mu, NULL);
18 pthread_rwlock_wrlock(p->mu);
20 p->sock = socket(AF_INET6, SOCK_STREAM, 0);
21 p->raddr = dragonnet_addr_parse_str(addr);
23 if (setsockopt(p->sock, SOL_SOCKET, SO_RCVTIMEO, &dragonnet_timeout,
24 sizeof dragonnet_timeout) < 0) {
26 dragonnet_peer_delete(p);
30 if (setsockopt(p->sock, SOL_SOCKET, SO_SNDTIMEO, &dragonnet_timeout,
31 sizeof dragonnet_timeout) < 0) {
33 dragonnet_peer_delete(p);
37 struct sockaddr_in6 sock_addr = dragonnet_addr_sock(p->raddr);
38 if (connect(p->sock, (const struct sockaddr *) &sock_addr,
39 sizeof sock_addr) < 0) {
41 dragonnet_peer_delete(p);
45 struct sockaddr_in6 sock_name;
46 socklen_t sock_namelen = sizeof sock_name;
48 if (getsockname(p->sock, (struct sockaddr *) &sock_name, &sock_namelen) < 0) {
49 perror("getsockname");
50 dragonnet_peer_delete(p);
54 p->laddr = dragonnet_addr_parse_sock(sock_name);
56 pthread_rwlock_unlock(p->mu);
60 void dragonnet_peer_run(DragonnetPeer *p)
62 pthread_t recv_thread;
63 pthread_create(&recv_thread, NULL, &dragonnet_peer_recv_thread, p);
64 pthread_join(recv_thread, NULL);
67 void dragonnet_peer_close(DragonnetPeer *p)
69 pthread_rwlock_wrlock(p->mu);
71 if (p->state == DRAGONNET_PEER_ACTIVE) {
72 shutdown(p->sock, SHUT_RDWR);
76 pthread_rwlock_unlock(p->mu);
79 void dragonnet_peer_delete(DragonnetPeer *p)
81 pthread_rwlock_destroy(p->mu);