00001 /***************************************************************************** 00002 * $Source: /cvsroot/charm/src/util/sockRoutines.h,v $ 00003 * $Author: gzheng $ 00004 * $Date: 2007-10-31 16:53:12 $ 00005 * $Revision: 1.23 $ 00006 *****************************************************************************/ 00007 00008 /************************************************************************** 00009 * 00010 * SKT - simple TCP and UDP socket routines. 00011 * All port numbers are taken and returned 00012 * in *host* byte order. This means you can hardcode port 00013 * numbers in the code normally, and they will be properly 00014 * translated even on little-endian machines. 00015 * 00016 * SOCKET is just a #define for "unsigned int". 00017 * 00018 * skt_ip_t is a flat bytes structure to hold an IP address-- 00019 * this is either 4 bytes (for IPv4) or 16 bytes (for IPv6). 00020 * It is always in network byte order. 00021 * 00022 * Errors are handled in the library by calling a user-overridable 00023 * abort function. 00024 * 00025 * skt_ip_t skt_my_ip(void) 00026 * - return the IP address of the current machine. 00027 * 00028 * skt_ip_t skt_lookup_ip(const char *name) 00029 * - return the IP address of the given machine (DNS or dotted decimal). 00030 * Returns 0 on failure. 00031 * 00032 * char *skt_print_ip(char *dest,skt_ip_t addr) 00033 * - Print the given IP address to the given destination as 00034 * dotted decimal. Dest must be at least 130 bytes long, 00035 * and will be returned. 00036 * 00037 * int skt_ip_match(skt_ip_t a,skt_ip_t b) 00038 * - Return 1 if the given IP addresses are identical. 00039 * 00040 * SOCKET skt_datagram(unsigned int *port, int bufsize) 00041 * 00042 * - creates a UDP datagram socket on the given port. 00043 * Performs the whole socket/bind/getsockname procedure. 00044 * Returns the actual port of the socket and 00045 * the file descriptor. Bufsize, if nonzero, controls the amount 00046 * of buffer space the kernel sets aside for the socket. 00047 * 00048 * SOCKET skt_server(unsigned int *port) 00049 * 00050 * - create a TCP server socket on the given port (0 for any port). 00051 * Performs the whole socket/bind/listen procedure. 00052 * Returns the actual port of the socket and the file descriptor. 00053 * 00054 * SOCKET skt_server_ip(unsigned int *port,skt_ip_t *ip) 00055 * 00056 * - create a TCP server socket on the given port and IP 00057 * Use 0 for any port and _skt_invalid_ip for any IP. 00058 * Performs the whole socket/bind/listen procedure. 00059 * Returns the actual port and IP address of the socket 00060 * and the file descriptor. 00061 * 00062 * SOCKET skt_accept(SOCKET src_fd,skt_ip_t *pip, unsigned int *port) 00063 * 00064 * - accepts a TCP connection to the specified server socket. Returns the 00065 * IP of the caller, the port number of the caller, and the file 00066 * descriptor to talk to the caller. 00067 * 00068 * SOCKET skt_connect(skt_ip_t ip, int port, int timeout) 00069 * 00070 * - Opens a TCP connection to the specified server. Returns a socket for 00071 * communication. 00072 * 00073 * void skt_close(SOCKET fd) 00074 * - Finishes communication on and closes the given socket. 00075 * 00076 * int skt_select1(SOCKET fd,int msec) 00077 * - Call select on the given socket, returning as soon as 00078 * the socket can recv or accept, or (failing that) in the given 00079 * number of milliseconds. Returns 0 on timeout; 1 on readable. 00080 * 00081 * int skt_recvN(SOCKET fd, void *buf,int nBytes) 00082 * int skt_sendN(SOCKET fd,const void *buf,int nBytes) 00083 * - Blocking send/recv nBytes on the given socket. 00084 * Retries if possible (e.g., if interrupted), but aborts 00085 * on serious errors. Returns zero or an abort code. 00086 * 00087 * int skt_sendV(SOCKET fd,int nBuffers,void **buffers,int *lengths) 00088 * - Blocking call to write from several buffers. This is much more 00089 * performance-critical than read-from-several buffers, because 00090 * individual sends go out as separate network packets, and include 00091 * a (35 ms!) timeout for subsequent short messages. Don't use more 00092 * than 8 buffers. 00093 * 00094 * void skt_set_idle(idleFunc f) 00095 * - Specify a routine to be called while waiting for the network. 00096 * Replaces any previous routine. 00097 * 00098 * void skt_set_abort(abortFunc f) 00099 * - Specify a routine to be called when an unrecoverable 00100 * (i.e., non-transient) socket error is encountered. 00101 * The default is to log the message to stderr and call exit(1). 00102 * 00103 **************************************************************************/ 00104 #ifndef __SOCK_ROUTINES_H 00105 #define __SOCK_ROUTINES_H 00106 00107 #include "conv-config.h" /*<- for CMK_NO_SOCKETS*/ 00108 00109 #ifdef CMK_NO_SOCKETS 00110 #define SOCKET int 00111 #define SOCKET_ERROR (-1) 00112 #define INVALID_SOCKET (SOCKET)(~0) 00113 typedef struct {int tag;} skt_ip_t; 00114 00115 extern skt_ip_t _skt_invalid_ip; 00116 skt_ip_t skt_my_ip(void); 00117 00118 #else /*Use actual sockets*/ 00119 00120 /*Preliminaries*/ 00121 #if defined(_WIN32) && ! defined(__CYGWIN__) 00122 /*For windows systems:*/ 00123 #include <winsock.h> 00124 static void sleep(int secs) {Sleep(1000*secs);} 00125 00126 #else 00127 /*For non-windows (UNIX) systems:*/ 00128 #include <sys/types.h> 00129 #include <sys/time.h> 00130 #include <sys/socket.h> 00131 #include <netinet/in.h> 00132 #include <arpa/inet.h> 00133 #include <netdb.h> 00134 #include <unistd.h> 00135 #include <fcntl.h> 00136 00137 #ifndef SOCKET 00138 # define SOCKET int 00139 # define INVALID_SOCKET (SOCKET)(~0) 00140 # define SOCKET_ERROR (-1) 00141 #endif /*def SOCKET*/ 00142 00143 #endif /*WIN32*/ 00144 00145 #ifdef __cplusplus 00146 extern "C" { 00147 #endif 00148 00149 /*Initialization*/ 00150 void skt_init(void); 00151 00152 /*Error and idle handling*/ 00153 typedef void (*skt_idleFn)(void); 00154 typedef int (*skt_abortFn)(int errCode,const char *msg); 00155 void skt_set_idle(skt_idleFn f); 00156 skt_abortFn skt_set_abort(skt_abortFn f); 00157 00158 /*DNS*/ 00159 typedef struct { /*IPv4 IP address*/ 00160 unsigned char data[4]; 00161 } skt_ip_t; 00162 extern skt_ip_t _skt_invalid_ip; 00163 skt_ip_t skt_my_ip(void); 00164 skt_ip_t skt_lookup_ip(const char *name); 00165 skt_ip_t skt_innode_my_ip(void); /* inner node version */ 00166 skt_ip_t skt_innode_lookup_ip(const char *name); 00167 00168 char *skt_print_ip(char *dest,skt_ip_t addr); 00169 int skt_ip_match(skt_ip_t a,skt_ip_t b); 00170 struct sockaddr_in skt_build_addr(skt_ip_t IP,int port); 00171 00172 /*UDP*/ 00173 SOCKET skt_datagram(unsigned int *port, int bufsize); 00174 00175 /*TCP*/ 00176 SOCKET skt_server(unsigned int *port); 00177 SOCKET skt_server_ip(unsigned int *port,skt_ip_t *ip); 00178 SOCKET skt_accept(SOCKET src_fd, skt_ip_t *pip, unsigned int *port); 00179 SOCKET skt_connect(skt_ip_t ip, int port, int timeout); 00180 00181 /*Utility*/ 00182 void skt_close(SOCKET fd); 00183 int skt_select1(SOCKET fd,int msec); 00184 void skt_setSockBuf(SOCKET skt, int bufsize); 00185 00186 /*Blocking Send/Recv*/ 00187 int skt_sendN(SOCKET hSocket,const void *pBuff,int nBytes); 00188 int skt_recvN(SOCKET hSocket, void *pBuff,int nBytes); 00189 int skt_sendV(SOCKET fd,int nBuffers,const void **buffers,int *lengths); 00190 00191 #ifdef __cplusplus 00192 }; 00193 #endif 00194 00195 #endif 00197 /*********************************** 00198 Conv-host messages: these are a simple 00199 binary format message, with the usual header, 00200 then data arrangement. 00201 00202 A fundamental data type is a ChMessageInt_t, 00203 a simple 4-byte big-endian (network byte order) 00204 integer. Routines are provided to read/write 00205 these integers on all platforms, regardless of 00206 endian-ness or native integer size. 00207 00208 ChMessage_recv reads a ChMessage on a socket. 00209 The ChMessage->data field is allocated to contain 00210 the entire message, and the header is filled out 00211 with the received fields. You may keep or dispose 00212 of the message memory with ChMessage_free. 00213 00214 ChMessageHeader_new fills out the fields of a header-- 00215 no allocation is done. 00216 00217 ChMessage_new fills out the header and allocates a 00218 data area of the given size. 00219 00220 ChMessage_send delivers the given ChMessage to a 00221 socket. You are still responsible for the ChMessage 00222 memory (use ChMessage_free). If you prefer, you may 00223 receive sizeof(ChMessageHeader) header bytes, then 00224 header->len data bytes on any socket yourself. 00225 */ 00226 #ifdef __cplusplus 00227 extern "C" { 00228 #endif 00229 00230 typedef struct { 00231 unsigned char data[4];/*4-byte, big-endian integer*/ 00232 } ChMessageInt_t; 00233 ChMessageInt_t ChMessageInt_new(unsigned int src); /*Convert integer to bytes*/ 00234 unsigned int ChMessageInt(ChMessageInt_t src); /*Convert bytes to integer*/ 00235 00236 typedef struct { 00237 unsigned char data[8];/*8-byte, big-endian integer*/ 00238 } ChMessageLong_t; 00239 ChMessageLong_t ChMessageLong_new(CMK_TYPEDEF_UINT8 src); /*Convert long integer to bytes*/ 00240 CMK_TYPEDEF_UINT8 ChMessageLong(ChMessageLong_t src); /*Convert bytes to long integer*/ 00241 00242 #define CH_TYPELEN 12 /*Maximum length for the message type field*/ 00243 typedef struct ChMessageHeader { 00244 ChMessageInt_t len; /*Length of message to follow (not incl. header)*/ 00245 char type[CH_TYPELEN];/*Kind of message to follow: 00246 (zero-terminated ASCII string) 00247 "getinfo" -- return a list of node IPs and control ports 00248 "req" -- a CCS message 00249 */ 00250 } ChMessageHeader; 00251 00252 typedef struct ChMessage { 00253 ChMessageHeader header; 00254 int len; /*Length of message data below*/ 00255 char *data; /*Pointer to heap-allocated data*/ 00256 } ChMessage; 00257 int ChMessage_recv(SOCKET fd,ChMessage *dst); 00258 int ChMessageHeader_recv(SOCKET fd,ChMessage *dst); 00259 int ChMessageData_recv(SOCKET fd,ChMessage *dst); 00260 void ChMessage_free(ChMessage *doomed); 00261 void ChMessageHeader_new(const char *type,int len,ChMessageHeader *dst); 00262 void ChMessage_new(const char *type,int len,ChMessage *dst); 00263 int ChMessage_send(SOCKET fd,const ChMessage *src); /*You must free after send*/ 00264 00265 00266 #if CMK_USE_IBVERBS 00267 typedef struct { 00268 ChMessageInt_t lid,qpn,psn; 00269 } ChInfiAddr ; 00270 #endif 00271 00272 00273 typedef struct { 00274 ChMessageInt_t nPE; /* Number of compute processors on this node */ 00275 #if CMK_USE_IBVERBS 00276 ChInfiAddr *qpList; 00277 #endif 00278 ChMessageInt_t dataport; /* node's data port (UDP or GM) */ 00279 ChMessageInt_t mach_id; /* node's hardware address (GM-only) */ 00280 #if CMK_USE_MX 00281 ChMessageLong_t nic_id; /* node's NIC hardware address (MX-only) */ 00282 #endif 00283 skt_ip_t IP; /* node's IP address */ 00284 } ChNodeinfo; 00285 00286 typedef struct { 00287 ChMessageInt_t nodeNo; 00288 ChNodeinfo info; 00289 } ChSingleNodeinfo; 00290 00291 /******* CCS Message type (included here for convenience) *******/ 00292 #define CCS_HANDLERLEN 32 /*Maximum length for the handler field*/ 00293 typedef struct { 00294 ChMessageInt_t len;/*Length of user data to follow header*/ 00295 ChMessageInt_t pe;/*Destination processor number*/ 00296 char handler[CCS_HANDLERLEN];/*Handler name for message to follow*/ 00297 } CcsMessageHeader; 00298 00299 #ifdef __cplusplus 00300 }; 00301 #endif 00302 00303 #endif /*SOCK_ROUTINES_H*/ 00304
1.5.1