util/sockRoutines.h

Go to the documentation of this file.
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 

Generated on Sun Jun 29 13:29:27 2008 for Charm++ by  doxygen 1.5.1