libxdas_net.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00039 #include <xdas.h>
00040 #include <xdasd.h>
00041 #include <xdas_buf.h>
00042 #include <xdas_wire.h>
00043 #include <xdas_debug.h>
00044
00045 #include "libxdas_impl.h"
00046
00047 #include <errno.h>
00048 #include <stdio.h>
00049
00055 #ifdef _WIN32
00056
00057 # define EWOULDBLOCK WSAEWOULDBLOCK
00058 # define EINPROGRESS WSAEINPROGRESS
00059 # define EALREADY WSAEALREADY
00060 # define ENOTSOCK WSAENOTSOCK
00061 # define EDESTADDRREQ WSAEDESTADDRREQ
00062 # define EMSGSIZE WSAEMSGSIZE
00063 # define EPROTOTYPE WSAEPROTOTYPE
00064 # define ENOPROTOOPT WSAENOPROTOOPT
00065 # define EPROTONOSUPPORT WSAEPROTONOSUPPORT
00066 # define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
00067 # define EOPNOTSUPP WSAEOPNOTSUPP
00068 # define EPFNOSUPPORT WSAEPFNOSUPPORT
00069 # define EAFNOSUPPORT WSAEAFNOSUPPORT
00070 # define EADDRINUSE WSAEADDRINUSE
00071 # define EADDRNOTAVAIL WSAEADDRNOTAVAIL
00072 # define ENETDOWN WSAENETDOWN
00073 # define ENETUNREACH WSAENETUNREACH
00074 # define ENETRESET WSAENETRESET
00075 # define ECONNABORTED WSAECONNABORTED
00076 # define ECONNRESET WSAECONNRESET
00077 # define ENOBUFS WSAENOBUFS
00078 # define EISCONN WSAEISCONN
00079 # define ENOTCONN WSAENOTCONN
00080 # define ESHUTDOWN WSAESHUTDOWN
00081 # define ETOOMANYREFS WSAETOOMANYREFS
00082 # define ETIMEDOUT WSAETIMEDOUT
00083 # define ECONNREFUSED WSAECONNREFUSED
00084 # define ELOOP WSAELOOP
00085 # define EHOSTDOWN WSAEHOSTDOWN
00086 # define EHOSTUNREACH WSAEHOSTUNREACH
00087 # define EREMOTE WSAEREMOTE
00088 #else
00089 # include <sys/un.h>
00090 #endif
00091
00092 #ifndef _WIN32
00093
00107 static void xdas_get_ipcpath(char * ipcpath, size_t ipcpathsz)
00108 {
00109 #define UNIT_TEST_RUN_PATH_ENVAR "XDAS_UNIT_TEST_RUN_PATH"
00110
00111 char * runpath = getenv(UNIT_TEST_RUN_PATH_ENVAR);
00112 if (runpath == 0)
00113 snprintf(ipcpath, ipcpathsz, XDASD_RUNPATH "/xdasd.ipc");
00114 else
00115 {
00116 snprintf(ipcpath, ipcpathsz, "%s/xdasd.ipc", runpath);
00117 printf("LIBXDAS: Using dynamic ipc path: %s.\n", ipcpath);
00118 }
00119 }
00120 #endif
00121
00129 static int xdas_map_network_error_to_minor(void)
00130 {
00131 #ifdef _WIN32
00132 int err = WSAGetLastError();
00133 #else
00134 int err = errno;
00135 #endif
00136 switch(err)
00137 {
00138 case 0: return 0;
00139
00140 case ENOTSOCK: return OXDAS_MS_NET_BAD_SOCKET;
00141 case ECONNABORTED: return OXDAS_MS_NET_CONN_ABORTED;
00142 case ECONNRESET: return OXDAS_MS_NET_CONN_RESET;
00143 case ENOTCONN: return OXDAS_MS_NET_NOT_CONNECTED;
00144 case ESHUTDOWN: return OXDAS_MS_NET_SHUTDOWN;
00145 case ETIMEDOUT: return OXDAS_MS_NET_TIMEDOUT;
00146 case ECONNREFUSED: return OXDAS_MS_NET_CONN_REFUSED;
00147
00148 case EWOULDBLOCK:
00149 case EINPROGRESS:
00150 case EALREADY:
00151 case EDESTADDRREQ:
00152 case EMSGSIZE:
00153 case EPROTOTYPE:
00154 case ENOPROTOOPT:
00155 case EPROTONOSUPPORT:
00156 case ESOCKTNOSUPPORT:
00157 case EOPNOTSUPP:
00158 case EPFNOSUPPORT:
00159 case EAFNOSUPPORT:
00160 case EADDRINUSE:
00161 case EADDRNOTAVAIL:
00162 case ENETDOWN:
00163 case ENETUNREACH:
00164 case ENETRESET:
00165 case ENOBUFS:
00166 case EISCONN:
00167 case ETOOMANYREFS:
00168 case ELOOP:
00169 case EHOSTDOWN:
00170 case EHOSTUNREACH:
00171 case EREMOTE:
00172 break;
00173 }
00174 return OXDAS_MS_NET_GENERAL_ERROR;
00175 }
00176
00183 void xdas_service_disconnect(xdas_session * xs)
00184 {
00185 if (xs->s != BAD_SOCKET)
00186 {
00187 closesocket(xs->s);
00188 xs->s = BAD_SOCKET;
00189 }
00190 }
00191
00201 int xdas_service_connect(int * minor, xdas_session * xs)
00202 {
00203 struct sockaddr_storage ss;
00204 int addrsz;
00205
00206 memset(&ss, 0, sizeof(ss));
00207
00208 #ifdef _WIN32
00209 {
00210 struct sockaddr_in * v4 = (struct sockaddr_in *)&ss;
00211 v4->sin_family = AF_INET;
00212 v4->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
00213 v4->sin_port = htons(XDASD_RESERVED_PORT);
00214 addrsz = sizeof(*v4);
00215 }
00216 #else
00217 {
00218 struct sockaddr_un * ud = (struct sockaddr_un *)&ss;
00219
00220 static char ipcpath[FILENAME_MAX] = "";
00221 if (*ipcpath == 0)
00222 xdas_get_ipcpath(ipcpath, sizeof(ipcpath));
00223
00224 ud->sun_family = AF_LOCAL;
00225 strncpy(ud->sun_path, ipcpath, sizeof(ud->sun_path));
00226 addrsz = sizeof(*ud);
00227 }
00228 #endif
00229
00230
00231 xdas_service_disconnect(xs);
00232
00233
00234 xs->s = socket(ss.ss_family, SOCK_STREAM, 0);
00235 if (connect(xs->s, (struct sockaddr *)&ss, addrsz) < 0)
00236 {
00237 *minor = xdas_map_network_error_to_minor();
00238 return XDAS_S_FAILURE;
00239 }
00240 return 0;
00241 }
00242
00257 int xdas_req_rsp(int * minorp, xdas_session * xs)
00258 {
00259 char peek[4];
00260 int scode, rspsz, bytes;
00261 xdas_buffer rsp;
00262
00263
00264 xdas_assert(minorp && xs && xs->req);
00265 if (!minorp || !xs || !xs->req)
00266 return -1;
00267
00268
00269 if (xs->s == BAD_SOCKET
00270 && (scode = xdas_service_connect(minorp, xs)) != 0)
00271 return scode;
00272
00273
00274 if ((bytes = send(xs->s, xs->req->start,
00275 (int)(xs->req->curpos - xs->req->start), 0)) < 0)
00276 return (*minorp = xdas_map_network_error_to_minor()), XDAS_S_FAILURE;
00277
00278
00279 bytes = recv(xs->s, peek, sizeof(peek), MSG_PEEK);
00280 xdas_assert(bytes < 0 || bytes == sizeof(peek));
00281 if (bytes < 0)
00282 return (*minorp = xdas_map_network_error_to_minor()), XDAS_S_FAILURE;
00283
00284 rspsz = (int)AS_UINT32(peek);
00285
00286
00287
00288 xdas_assert(rspsz >= 12 && rspsz < 4096);
00289
00290 if ((rsp = xdas_buffer_realloc(xs->rsp, rspsz)) == 0)
00291 return (*minorp = OXDAS_MS_OUT_OF_MEMORY), XDAS_S_FAILURE;
00292 rsp->curpos = rsp->start;
00293 xs->rsp = rsp;
00294
00295
00296 while (rspsz && (bytes = recv(xs->s, rsp->curpos, rspsz, 0)) > 0)
00297 {
00298 rsp->curpos += bytes;
00299 rspsz -= bytes;
00300 }
00301
00302
00303 if (bytes <= 0)
00304 return (*minorp = xdas_map_network_error_to_minor()), XDAS_S_FAILURE;
00305
00306
00307 rsp->curpos = rsp->start + 4;
00308 scode = (int)xdas_buffer_get_uint32(rsp);
00309 *minorp = (int)xdas_buffer_get_uint32(rsp);
00310
00311 return scode;
00312 }
00313