a dummy function defined when NO_SOCK.
[charm.git] / src / util / sockRoutines.h
1 /*****************************************************************************
2  * $Source$
3  * $Author$
4  * $Date$
5  * $Revision$
6  *****************************************************************************/
7
8 /**************************************************************************
9  *
10  * SKT - simple TCP and UDP socket routines.  
11  *  All port numbers are taken and returned 
12  *  in *host* byte order.  This means you can hardcode port
13  *  numbers in the code normally, and they will be properly 
14  *  translated even on little-endian machines.
15  *
16  *  SOCKET is just a #define for "unsigned int".
17  *
18  *  skt_ip_t is a flat bytes structure to hold an IP address--
19  *  this is either 4 bytes (for IPv4) or 16 bytes (for IPv6).
20  *  It is always in network byte order.
21  *
22  *  Errors are handled in the library by calling a user-overridable
23  *  abort function.
24  * 
25  * skt_ip_t skt_my_ip(void)
26  *   - return the IP address of the current machine.
27  *
28  * skt_ip_t skt_lookup_ip(const char *name)
29  *   - return the IP address of the given machine (DNS or dotted decimal).
30  *     Returns 0 on failure.
31  *
32  * char *skt_print_ip(char *dest,skt_ip_t addr)
33  *   - Print the given IP address to the given destination as
34  *     dotted decimal.  Dest must be at least 130 bytes long, 
35  *     and will be returned.
36  *
37  * int skt_ip_match(skt_ip_t a,skt_ip_t b)
38  *   - Return 1 if the given IP addresses are identical.
39  *
40  * SOCKET skt_datagram(unsigned int *port, int bufsize)
41  *
42  *   - creates a UDP datagram socket on the given port.  
43  *     Performs the whole socket/bind/getsockname procedure.  
44  *     Returns the actual port of the socket and
45  *     the file descriptor.  Bufsize, if nonzero, controls the amount
46  *     of buffer space the kernel sets aside for the socket.
47  *
48  * SOCKET skt_server(unsigned int *port)
49  *
50  *   - create a TCP server socket on the given port (0 for any port).  
51  *     Performs the whole socket/bind/listen procedure.  
52  *     Returns the actual port of the socket and the file descriptor.
53  *
54  * SOCKET skt_server_ip(unsigned int *port,skt_ip_t *ip)
55  *
56  *   - create a TCP server socket on the given port and IP
57  *     Use 0 for any port and _skt_invalid_ip for any IP.  
58  *     Performs the whole socket/bind/listen procedure.  
59  *     Returns the actual port and IP address of the socket 
60  *     and the file descriptor.
61  *
62  * SOCKET skt_accept(SOCKET src_fd,skt_ip_t *pip, unsigned int *port)
63  *
64  *   - accepts a TCP connection to the specified server socket.  Returns the
65  *     IP of the caller, the port number of the caller, and the file
66  *     descriptor to talk to the caller.
67  *
68  * SOCKET skt_connect(skt_ip_t ip, int port, int timeout)
69  *
70  *   - Opens a TCP connection to the specified server.  Returns a socket for
71  *     communication.
72  *
73  * void skt_close(SOCKET fd)
74  *   - Finishes communication on and closes the given socket.
75  *
76  * int skt_select1(SOCKET fd,int msec)
77  *   - Call select on the given socket, returning as soon as
78  *     the socket can recv or accept, or (failing that) in the given
79  *     number of milliseconds.  Returns 0 on timeout; 1 on readable.
80  *
81  * int skt_recvN(SOCKET fd,      void *buf,int nBytes)
82  * int skt_sendN(SOCKET fd,const void *buf,int nBytes)
83  *   - Blocking send/recv nBytes on the given socket.
84  *     Retries if possible (e.g., if interrupted), but aborts 
85  *     on serious errors.  Returns zero or an abort code.
86  *
87  * int skt_sendV(SOCKET fd,int nBuffers,void **buffers,int *lengths)
88  *   - Blocking call to write from several buffers.  This is much more
89  *     performance-critical than read-from-several buffers, because 
90  *     individual sends go out as separate network packets, and include
91  *     a (35 ms!) timeout for subsequent short messages.  Don't use more
92  *     than 8 buffers.
93  * 
94  * void skt_set_idle(idleFunc f)
95  *   - Specify a routine to be called while waiting for the network.
96  *     Replaces any previous routine.
97  * 
98  * void skt_set_abort(abortFunc f)
99  *   - Specify a routine to be called when an unrecoverable
100  *     (i.e., non-transient) socket error is encountered.
101  *     The default is to log the message to stderr and call exit(1).
102  *
103  **************************************************************************/
104 #ifndef __SOCK_ROUTINES_H
105 #define __SOCK_ROUTINES_H
106
107 #include "conv-config.h" /*<- for CMK_NO_SOCKETS*/
108
109 #ifdef CMK_NO_SOCKETS
110 #define SOCKET int
111 #define SOCKET_ERROR (-1)
112 #define INVALID_SOCKET (SOCKET)(~0)
113 typedef struct {int tag;} skt_ip_t;
114
115 extern skt_ip_t _skt_invalid_ip;
116 skt_ip_t skt_my_ip(void);
117
118 #else /*Use actual sockets*/
119
120 /*Preliminaries*/
121 #if defined(_WIN32) && ! defined(__CYGWIN__)
122   /*For windows systems:*/
123 #include <winsock.h>
124 static void sleep(int secs) {Sleep(1000*secs);}
125
126 #else
127   /*For non-windows (UNIX) systems:*/
128 #include <sys/types.h>
129 #include <sys/time.h>
130 #include <sys/socket.h>
131 #include <netinet/in.h>
132 #include <arpa/inet.h>
133 #include <netdb.h>
134 #include <unistd.h>
135 #include <fcntl.h>
136
137 #ifndef SOCKET
138 #  define SOCKET int
139 #  define INVALID_SOCKET (SOCKET)(~0)
140 #  define SOCKET_ERROR (-1)
141 #endif /*def SOCKET*/
142
143 #endif /*WIN32*/
144
145 #ifdef __cplusplus
146 extern "C" {
147 #endif
148
149 /*Initialization*/
150 void skt_init(void);
151
152 /*Error and idle handling*/
153 typedef void (*skt_idleFn)(void);
154 typedef int (*skt_abortFn)(int errCode,const char *msg);
155 void skt_set_idle(skt_idleFn f);
156 skt_abortFn skt_set_abort(skt_abortFn f);
157
158 /*DNS*/
159 typedef struct { /*IPv4 IP address*/
160         unsigned char data[4];
161 } skt_ip_t;
162 extern skt_ip_t _skt_invalid_ip;
163 skt_ip_t skt_my_ip(void);
164 skt_ip_t skt_lookup_ip(const char *name);
165 skt_ip_t skt_innode_my_ip(void);        /* inner node version */
166 skt_ip_t skt_innode_lookup_ip(const char *name);
167
168 char *skt_print_ip(char *dest,skt_ip_t addr);
169 int skt_ip_match(skt_ip_t a,skt_ip_t b);
170 struct sockaddr_in skt_build_addr(skt_ip_t IP,int port);
171
172 /*UDP*/
173 SOCKET skt_datagram(unsigned int *port, int bufsize);
174
175 /*TCP*/
176 SOCKET skt_server(unsigned int *port);
177 SOCKET skt_server_ip(unsigned int *port,skt_ip_t *ip);
178 SOCKET skt_accept(SOCKET src_fd, skt_ip_t *pip, unsigned int *port);
179 SOCKET skt_connect(skt_ip_t ip, int port, int timeout);
180
181 /*Utility*/
182 void skt_close(SOCKET fd);
183 int skt_select1(SOCKET fd,int msec);
184 void skt_setSockBuf(SOCKET skt, int bufsize);
185
186 /*Blocking Send/Recv*/
187 int skt_sendN(SOCKET hSocket,const void *pBuff,int nBytes);
188 int skt_recvN(SOCKET hSocket,      void *pBuff,int nBytes);
189 int skt_sendV(SOCKET fd,int nBuffers,const void **buffers,int *lengths);
190
191 #ifdef __cplusplus
192 };
193 #endif
194
195 #endif /*!CMK_NO_SOCKETS*/
196
197 /***********************************
198 Conv-host messages: these are a simple
199 binary format message, with the usual header,
200 then data arrangement.
201
202 A fundamental data type is a ChMessageInt_t,
203 a simple 4-byte big-endian (network byte order)
204 integer.  Routines are provided to read/write
205 these integers on all platforms, regardless of 
206 endian-ness or native integer size.
207
208  ChMessage_recv reads a ChMessage on a socket.
209 The ChMessage->data field is allocated to contain
210 the entire message, and the header is filled out
211 with the received fields.  You may keep or dispose 
212 of the message memory with ChMessage_free.
213
214  ChMessageHeader_new fills out the fields of a header--
215 no allocation is done.
216
217  ChMessage_new fills out the header and allocates a 
218 data area of the given size.
219
220  ChMessage_send delivers the given ChMessage to a
221 socket.  You are still responsible for the ChMessage
222 memory (use ChMessage_free).  If you prefer, you may
223 receive sizeof(ChMessageHeader) header bytes, then 
224 header->len data bytes on any socket yourself.
225 */
226 #ifdef __cplusplus
227 extern "C" {
228 #endif
229
230 typedef struct {
231   unsigned char data[4];/*4-byte, big-endian integer*/
232 } ChMessageInt_t;
233 ChMessageInt_t ChMessageInt_new(unsigned int src); /*Convert integer to bytes*/
234 unsigned int ChMessageInt(ChMessageInt_t src); /*Convert bytes to integer*/
235
236 typedef struct {
237   unsigned char data[8];/*8-byte, big-endian integer*/
238 } ChMessageLong_t;
239 ChMessageLong_t ChMessageLong_new(CMK_TYPEDEF_UINT8 src); /*Convert long integer to bytes*/
240 CMK_TYPEDEF_UINT8 ChMessageLong(ChMessageLong_t src); /*Convert bytes to long integer*/
241
242 #define CH_TYPELEN 12 /*Maximum length for the message type field*/
243 typedef struct ChMessageHeader {
244   ChMessageInt_t len; /*Length of message to follow (not incl. header)*/
245   char type[CH_TYPELEN];/*Kind of message to follow:
246      (zero-terminated ASCII string) 
247      "getinfo" -- return a list of node IPs and control ports
248      "req" -- a CCS message
249      */
250 } ChMessageHeader;
251
252 typedef struct ChMessage {
253   ChMessageHeader header;
254   int len; /*Length of message data below*/
255   char *data; /*Pointer to heap-allocated data*/
256 } ChMessage;
257 int ChMessage_recv(SOCKET fd,ChMessage *dst);
258 int ChMessageHeader_recv(SOCKET fd,ChMessage *dst);
259 int ChMessageData_recv(SOCKET fd,ChMessage *dst);
260 void ChMessage_free(ChMessage *doomed);
261 void ChMessageHeader_new(const char *type,int len,ChMessageHeader *dst);
262 void ChMessage_new(const char *type,int len,ChMessage *dst);
263 int ChMessage_send(SOCKET fd,const ChMessage *src); /*You must free after send*/
264
265
266 #if CMK_USE_IBVERBS
267 typedef struct {
268         ChMessageInt_t lid,qpn,psn;
269 } ChInfiAddr ;
270 #endif
271
272
273 typedef struct {
274         ChMessageInt_t nPE; /* Number of compute processors on this node */
275 #if CMK_USE_IBVERBS
276         ChInfiAddr *qpList; /** An array of queue pair identifiers of length CmiNumNodes()-1*/
277 #endif
278         ChMessageInt_t dataport; /* node's data port (UDP or GM) */
279         ChMessageInt_t mach_id; /* node's hardware address (GM-only) */
280 #if CMK_USE_MX
281         ChMessageLong_t nic_id; /* node's NIC hardware address (MX-only) */
282 #endif
283         skt_ip_t IP; /* node's IP address */
284 } ChNodeinfo;
285
286 typedef struct {
287         ChMessageInt_t nodeNo;
288         ChNodeinfo info;
289 } ChSingleNodeinfo;
290
291 /******* CCS Message type (included here for convenience) *******/
292 #define CCS_HANDLERLEN 32 /*Maximum length for the handler field*/
293 typedef struct {
294   ChMessageInt_t len;/*Length of user data to follow header*/
295   ChMessageInt_t pe;/*Destination processor number*/
296   char handler[CCS_HANDLERLEN];/*Handler name for message to follow*/
297 } CcsMessageHeader;
298
299 #ifdef __cplusplus
300 };
301 #endif
302
303 #endif /*SOCK_ROUTINES_H*/
304