1aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz
2aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#include "pipe/p_compiler.h"
3aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#include "util/u_network.h"
4aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#include "util/u_debug.h"
5aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz
6aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
7b04470b0bce6a24a74a0ec8cf16d9d3f03aff5f2Michal Krol#  include <winsock2.h>
8aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#  include <windows.h>
968657183b0e42093777034460e0a93624b7ba501Alan Coopersmith#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || \
1068657183b0e42093777034460e0a93624b7ba501Alan Coopersmith   defined(PIPE_OS_APPLE) || defined(PIPE_OS_CYGWIN) || defined(PIPE_OS_SOLARIS)
11aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#  include <sys/socket.h>
12aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#  include <netinet/in.h>
13aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#  include <unistd.h>
14aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#  include <fcntl.h>
15aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#  include <netdb.h>
16aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#else
17aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#  warning "No socket implementation"
18aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#endif
19aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz
20aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzboolean
21aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzu_socket_init()
22aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz{
23aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
24aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   WORD wVersionRequested;
25aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   WSADATA wsaData;
26aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   int err;
27aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz
28aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
29aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   wVersionRequested = MAKEWORD(1, 1);
30aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz
31aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   err = WSAStartup(wVersionRequested, &wsaData);
32aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   if (err != 0) {
33aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz      debug_printf("WSAStartup failed with error: %d\n", err);
34aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz      return FALSE;
35aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   }
36aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   return TRUE;
37aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#elif defined(PIPE_HAVE_SOCKETS)
38aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   return TRUE;
39aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#else
40aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   return FALSE;
41aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#endif
42aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz}
43aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz
44aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzvoid
45aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzu_socket_stop()
46aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz{
47aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
48aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   WSACleanup();
49aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#endif
50aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz}
51aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz
52aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzvoid
53aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzu_socket_close(int s)
54aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz{
55aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   if (s < 0)
56aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz      return;
57aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz
5868657183b0e42093777034460e0a93624b7ba501Alan Coopersmith#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) \
5968657183b0e42093777034460e0a93624b7ba501Alan Coopersmith    || defined(PIPE_OS_APPLE) || defined(PIPE_OS_SOLARIS)
60aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   shutdown(s, SHUT_RDWR);
61aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   close(s);
62aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
63aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   shutdown(s, SD_BOTH);
64aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   closesocket(s);
65aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#else
66aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   assert(0);
67aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#endif
68aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz}
69aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz
70aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzint u_socket_accept(int s)
71aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz{
72aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#if defined(PIPE_HAVE_SOCKETS)
73aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   return accept(s, NULL, NULL);
74aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#else
75aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   return -1;
76aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#endif
77aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz}
78aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz
79aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzint
80aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzu_socket_send(int s, void *data, size_t size)
81aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz{
82aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#if defined(PIPE_HAVE_SOCKETS)
83aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   return send(s, data, size, 0);
84aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#else
85aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   return -1;
86aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#endif
87aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz}
88aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz
89aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzint
90aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzu_socket_peek(int s, void *data, size_t size)
91aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz{
92aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#if defined(PIPE_HAVE_SOCKETS)
93aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   return recv(s, data, size, MSG_PEEK);
94aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#else
95aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   return -1;
96aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#endif
97aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz}
98aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz
99aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzint
100aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzu_socket_recv(int s, void *data, size_t size)
101aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz{
102aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#if defined(PIPE_HAVE_SOCKETS)
103aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   return recv(s, data, size, 0);
104aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#else
105aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   return -1;
106aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#endif
107aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz}
108aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz
109aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzint
110aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzu_socket_connect(const char *hostname, uint16_t port)
111aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz{
112aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#if defined(PIPE_HAVE_SOCKETS)
113aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   int s;
114aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   struct sockaddr_in sa;
115aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   struct hostent *host = NULL;
116aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz
117aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   memset(&sa, 0, sizeof(struct sockaddr_in));
118aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   host = gethostbyname(hostname);
119aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   if (!host)
120aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz      return -1;
121aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz
1227df06e7e9d5d5ac0a5a2fa0af11afa7f5241c5a4Vinson Lee   memcpy((char *)&sa.sin_addr,host->h_addr_list[0],host->h_length);
123aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   sa.sin_family= host->h_addrtype;
124aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   sa.sin_port = htons(port);
125aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz
126aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   s = socket(host->h_addrtype, SOCK_STREAM, IPPROTO_TCP);
127aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   if (s < 0)
128aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz      return -1;
129aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz
130aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   if (connect(s, (struct sockaddr *)&sa, sizeof(sa))) {
131aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz      u_socket_close(s);
132aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz      return -1;
133aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   }
134aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz
135aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   return s;
136aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#else
137aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   assert(0);
138aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   return -1;
139aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#endif
140aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz}
141aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz
142aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzint
143aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzu_socket_listen_on_port(uint16_t portnum)
144aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz{
145aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#if defined(PIPE_HAVE_SOCKETS)
146aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   int s;
147aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   struct sockaddr_in sa;
148aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   memset(&sa, 0, sizeof(struct sockaddr_in));
149aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz
150aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   sa.sin_family = AF_INET;
151aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   sa.sin_port = htons(portnum);
152aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz
153aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
154aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   if (s < 0)
155aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz      return -1;
156aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz
157aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   if (bind(s, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) == -1) {
158aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz      u_socket_close(s);
159aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz      return -1;
160aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   }
161aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz
162aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   listen(s, 0);
163aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz
164aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   return s;
165aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#else
166aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   assert(0);
167aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   return -1;
168aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#endif
169aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz}
170aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz
171aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzvoid
172aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantzu_socket_block(int s, boolean block)
173aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz{
17468657183b0e42093777034460e0a93624b7ba501Alan Coopersmith#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) \
17568657183b0e42093777034460e0a93624b7ba501Alan Coopersmith    || defined(PIPE_OS_APPLE) || defined(PIPE_OS_SOLARIS)
176aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   int old = fcntl(s, F_GETFL, 0);
177aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   if (old == -1)
178aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz      return;
179aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz
180aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   /* TODO obey block */
181aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   if (block)
182aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz      fcntl(s, F_SETFL, old & ~O_NONBLOCK);
183aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   else
184aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz      fcntl(s, F_SETFL, old | O_NONBLOCK);
185aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
186aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   u_long iMode = block ? 0 : 1;
187aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   ioctlsocket(s, FIONBIO, &iMode);
188aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#else
189aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz   assert(0);
190aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz#endif
191aee1a6f70413235c0c4c2c2adfca97d5128a155eJakob Bornecrantz}
192