timer: handle time going backwards.
[ccan] / ccan / net / net.h
1 /* Licensed under BSD-MIT - see LICENSE file for details */
2 #ifndef CCAN_NET_H
3 #define CCAN_NET_H
4 #include <sys/types.h>
5 #include <sys/socket.h>
6 #include <netdb.h>
7 #include <stdbool.h>
8
9 struct pollfd;
10
11 /**
12  * net_client_lookup - look up a network name to connect to.
13  * @hostname: the name to look up
14  * @service: the service to look up
15  * @family: Usually AF_UNSPEC, otherwise AF_INET or AF_INET6.
16  * @socktype: SOCK_DGRAM or SOCK_STREAM.
17  *
18  * This will do a synchronous lookup of a given name, returning a linked list
19  * of results, or NULL on error.  You should use freeaddrinfo() to free it.
20  *
21  * Example:
22  *      #include <stdio.h>
23  *      #include <poll.h>
24  *      #include <err.h>
25  *      ...
26  *      struct addrinfo *addr;
27  *
28  *      // Get a TCP connection to ccan.ozlabs.org daytime port.
29  *      addr = net_client_lookup("ccan.ozlabs.org", "daytime",
30  *                               AF_UNSPEC, SOCK_STREAM);
31  *      if (!addr)
32  *              errx(1, "Failed to look up daytime at ccan.ozlabs.org");
33  */
34 struct addrinfo *net_client_lookup(const char *hostname,
35                                    const char *service,
36                                    int family,
37                                    int socktype);
38
39 /**
40  * net_connect - connect to a server
41  * @addrinfo: linked list struct addrinfo (usually from net_client_lookup).
42  *
43  * This synchronously connects to a server described by @addrinfo, or returns
44  * -1 on error (and sets errno).
45  *
46  * Example:
47  *      int fd;
48  *      ...
49  *      fd = net_connect(addr);
50  *      if (fd < 0)
51  *              err(1, "Failed to connect to ccan.ozlabs.org");
52  *      freeaddrinfo(addr);
53  */
54 int net_connect(const struct addrinfo *addrinfo);
55
56 /**
57  * net_connect_async - initiate connect to a server
58  * @addrinfo: linked list struct addrinfo (usually from net_client_lookup).
59  * @pfds: array of two struct pollfd.
60  *
61  * This begins connecting to a server described by @addrinfo,
62  * and places the one or two file descriptors into pfds[0] and pfds[1].
63  * It returns a valid file descriptor if connect() returned immediately.
64  *
65  * Otherwise it returns -1 and sets errno, most likely EINPROGRESS.
66  * In this case, poll() on pfds and call net_connect_complete().
67  *
68  * Example:
69  *      struct pollfd pfds[2];
70  *      ...
71  *      fd = net_connect_async(addr, pfds);
72  *      if (fd < 0 && errno != EINPROGRESS)
73  *              err(1, "Failed to connect to ccan.ozlabs.org");
74  */
75 int net_connect_async(const struct addrinfo *addrinfo, struct pollfd *pfds);
76
77 /**
78  * net_connect_complete - complete net_connect_async call.
79  * @pfds: array of two struct pollfd handed to net_connect_async.
80  *
81  * When poll() reports some activity, this determines whether a connection
82  * has completed.  If so, it cleans up and returns the connected fd.
83  * Otherwise, it returns -1, and sets errno (usually EINPROGRESS).
84  *
85  * Example:
86  *      // After net_connect_async.
87  *      while (fd < 0 && errno == EINPROGRESS) {
88  *              // Wait for activity...
89  *              poll(pfds, 2, -1);
90  *              fd = net_connect_complete(pfds);
91  *      }
92  *      if (fd < 0)
93  *              err(1, "connecting");
94  *      printf("Connected on fd %i!\n", fd);
95  */
96 int net_connect_complete(struct pollfd *pfds);
97
98 /**
99  * net_connect_abort - abort a net_connect_async call.
100  * @pfds: array of two struct pollfd handed to net_connect_async.
101  *
102  * Closes the file descriptors.
103  *
104  * Example:
105  *      // After net_connect_async.
106  *      if (poll(pfds, 2, 1000) == 0) { // Timeout.
107  *              net_connect_abort(pfds);
108  *              fd = -1;
109  *      } else {
110  *              fd = net_connect_complete(pfds);
111  *              if (fd < 0)
112  *                      err(1, "connecting");
113  *      }
114  */
115 void net_connect_abort(struct pollfd *pfds);
116
117 /**
118  * net_server_lookup - look up a service name to bind to.
119  * @service: the service to look up
120  * @family: Usually AF_UNSPEC, otherwise AF_INET or AF_INET6.
121  * @socktype: SOCK_DGRAM or SOCK_STREAM.
122  *
123  * This will do a synchronous lookup of a given name, returning a linked list
124  * of results, or NULL on error.  You should use freeaddrinfo() to free it.
125  *
126  * Example:
127  *      #include <stdio.h>
128  *      #include <err.h>
129  *      ...
130  *      struct addrinfo *addr;
131  *
132  *      // Get address(es) to bind for our service.
133  *      addr = net_server_lookup("8888", AF_UNSPEC, SOCK_STREAM);
134  *      if (!addr)
135  *              errx(1, "Failed to look up 8888 to bind to");
136  */
137 struct addrinfo *net_server_lookup(const char *service,
138                                    int family,
139                                    int socktype);
140
141 /**
142  * net_bind - create listening socket(s)
143  * @addrinfo: the address(es) to bind to.
144  * @fds: array of two fds.
145  *
146  * This will create one (or if necessary) two sockets, mark them
147  * SO_REUSEADDR, bind them to the given address(es), and make them
148  * listen() (if the socket type is SOCK_STREAM or SOCK_SEQPACKET).
149  *
150  * Returns -1 (and sets errno) on error, or 1 or 2 depending on how many
151  * @fds are valid.
152  *
153  * Example:
154  *      int fds[2], i, num_fds;
155  *
156  *      num_fds = net_bind(addr, fds);
157  *      if (num_fds < 0)
158  *              err(1, "Failed to listen on port 8888");
159  *
160  *      for (i = 0; i < num_fds; i++)
161  *              printf(" Got fd %u/%u: %i\n", i, num_fds, fds[i]);
162  */
163 int net_bind(const struct addrinfo *addrinfo, int fds[2]);
164 #endif /* CCAN_NET_H */