io_socket.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  $RCSfile$
00003                              -------------------
00004     cvs         : $Id: crypttoken.h 1113 2007-01-10 09:14:16Z martin $
00005     begin       : Wed Mar 16 2005
00006     copyright   : (C) 2005 by Martin Preuss
00007     email       : martin@libchipcard.de
00008 
00009  ***************************************************************************
00010  *          Please see toplevel file COPYING for license details           *
00011  ***************************************************************************/
00012 
00013 #ifdef HAVE_CONFIG_H
00014 # include <config.h>
00015 #endif
00016 
00017 
00018 #include "io_socket_p.h"
00019 #include <gwenhywfar/iolayer_be.h>
00020 #include <gwenhywfar/iorequest_be.h>
00021 
00022 #include "i18n_l.h"
00023 #include <gwenhywfar/misc.h>
00024 #include <gwenhywfar/debug.h>
00025 #include <gwenhywfar/gui.h>
00026 
00027 #include <gwenhywfar/text.h> /* debug */
00028 
00029 #include <assert.h>
00030 #include <errno.h>
00031 #include <string.h>
00032 #include <unistd.h>
00033 #include <fcntl.h>
00034 
00035 
00036 //#define HACK_FOR_DAVID
00037 
00038 
00039 GWEN_INHERIT(GWEN_IO_LAYER, GWEN_IO_LAYER_SOCKET)
00040 
00041 
00042 
00043 GWEN_IO_LAYER *GWEN_Io_LayerSocket_new(GWEN_SOCKET *sk) {
00044   GWEN_IO_LAYER *io;
00045   GWEN_IO_LAYER_SOCKET *xio;
00046 
00047   io=GWEN_Io_Layer_new(GWEN_IO_LAYER_SOCKET_TYPE, NULL);
00048   assert(io);
00049   GWEN_NEW_OBJECT(GWEN_IO_LAYER_SOCKET, xio);
00050   assert(xio);
00051   GWEN_INHERIT_SETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_SOCKET, io, xio, GWEN_Io_LayerSocket_freeData);
00052 
00053   GWEN_Io_Layer_SetWorkOnRequestsFn(io, GWEN_Io_LayerSocket_WorkOnRequests);
00054   GWEN_Io_Layer_SetAddRequestFn(io, GWEN_Io_LayerSocket_AddRequest);
00055   GWEN_Io_Layer_SetDelRequestFn(io, GWEN_Io_LayerSocket_DelRequest);
00056   GWEN_Io_Layer_SetHasWaitingRequestsFn(io, GWEN_Io_LayerSocket_HasWaitingRequests);
00057   GWEN_Io_Layer_SetAddWaitingSocketsFn(io, GWEN_Io_LayerSocket_AddWaitingSockets);
00058   GWEN_Io_Layer_SetListenFn(io, GWEN_Io_LayerSocket_Listen);
00059 
00060   xio->socket=sk;
00061 
00062   GWEN_Io_Layer_SetStatus(io, GWEN_Io_Layer_StatusUnconnected);
00063 
00064 
00065   return io;
00066 }
00067 
00068 
00069 
00070 GWENHYWFAR_CB
00071 void GWEN_Io_LayerSocket_freeData(void *bp, void *p) {
00072   GWEN_IO_LAYER *io;
00073   GWEN_IO_LAYER_SOCKET *xio;
00074   uint32_t lflags;
00075 
00076   io=(GWEN_IO_LAYER*) bp;
00077   assert(io);
00078   xio=(GWEN_IO_LAYER_SOCKET*) p;
00079   assert(xio);
00080 
00081   GWEN_Io_LayerSocket_AbortRequests(io, GWEN_ERROR_ABORTED);
00082   lflags=GWEN_Io_Layer_GetFlags(io);
00083 
00084   /* close socket (if it not already is) */
00085   if (!(lflags & GWEN_IO_LAYER_FLAGS_DONTCLOSE))
00086     GWEN_Socket_Close(xio->socket);
00087 
00088   /* free ressource (if requested) */
00089   if (lflags & GWEN_IO_LAYER_FLAGS_TAKEOVER) {
00090     GWEN_Socket_free(xio->socket);
00091     xio->socket=(GWEN_SOCKET*) -1;
00092   }
00093 
00094   /* done */
00095   GWEN_FREE_OBJECT(xio);
00096 }
00097 
00098 
00099 
00100 GWEN_INETADDRESS *GWEN_Io_LayerSocket_GetLocalAddr(const GWEN_IO_LAYER *io) {
00101   GWEN_IO_LAYER_SOCKET *xio;
00102 
00103   assert(io);
00104   xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_SOCKET, io);
00105   assert(xio);
00106 
00107   return xio->localAddr;
00108 }
00109 
00110 
00111 
00112 void GWEN_Io_LayerSocket_SetLocalAddr(GWEN_IO_LAYER *io, const GWEN_INETADDRESS *addr) {
00113   GWEN_IO_LAYER_SOCKET *xio;
00114 
00115   assert(io);
00116   xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_SOCKET, io);
00117   assert(xio);
00118 
00119   GWEN_InetAddr_free(xio->localAddr);
00120   if (addr) xio->localAddr=GWEN_InetAddr_dup(addr);
00121   else xio->localAddr=NULL;
00122 }
00123 
00124 
00125 
00126 GWEN_INETADDRESS *GWEN_Io_LayerSocket_GetPeerAddr(const GWEN_IO_LAYER *io) {
00127   GWEN_IO_LAYER_SOCKET *xio;
00128 
00129   assert(io);
00130   xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_SOCKET, io);
00131   assert(xio);
00132 
00133   return xio->peerAddr;
00134 }
00135 
00136 
00137 
00138 void GWEN_Io_LayerSocket_SetPeerAddr(GWEN_IO_LAYER *io, const GWEN_INETADDRESS *addr) {
00139   GWEN_IO_LAYER_SOCKET *xio;
00140 
00141   assert(io);
00142   xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_SOCKET, io);
00143   assert(xio);
00144 
00145   GWEN_InetAddr_free(xio->peerAddr);
00146   if (addr) xio->peerAddr=GWEN_InetAddr_dup(addr);
00147   else xio->peerAddr=NULL;
00148 }
00149 
00150 
00151 
00152 GWEN_SOCKET *GWEN_Io_LayerSocket_GetSocket(const GWEN_IO_LAYER *io) {
00153   GWEN_IO_LAYER_SOCKET *xio;
00154 
00155   assert(io);
00156   xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_SOCKET, io);
00157   assert(xio);
00158 
00159   return xio->socket;
00160 }
00161 
00162 
00163 
00164 void GWEN_Io_LayerSocket_AbortRequests(GWEN_IO_LAYER *io, int errorCode) {
00165   GWEN_IO_LAYER_SOCKET *xio;
00166 
00167   assert(io);
00168   xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_SOCKET, io);
00169   assert(xio);
00170 
00171   if (xio->connectRequest) {
00172     GWEN_IO_REQUEST *r;
00173 
00174     r=xio->connectRequest;
00175     xio->connectRequest=NULL;
00176     GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, errorCode);
00177     GWEN_Io_Request_free(r);
00178   }
00179   if (xio->readRequest) {
00180     GWEN_IO_REQUEST *r;
00181 
00182     r=xio->readRequest;
00183     xio->readRequest=NULL;
00184     GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, errorCode);
00185     GWEN_Io_Request_free(r);
00186   }
00187   if (xio->writeRequest) {
00188     GWEN_IO_REQUEST *r;
00189 
00190    r=xio->writeRequest;
00191    xio->writeRequest=NULL;
00192    GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, errorCode);
00193    GWEN_Io_Request_free(r);
00194   }
00195 }
00196 
00197 
00198 
00199 GWEN_IO_LAYER_WORKRESULT GWEN_Io_LayerSocket_CheckForIncoming(GWEN_IO_LAYER *io) {
00200   GWEN_IO_LAYER_SOCKET *xio;
00201   int doneSomething=0;
00202 
00203   assert(io);
00204   xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_SOCKET, io);
00205   assert(xio);
00206 
00207   if (GWEN_Io_Layer_GetStatus(io)==GWEN_Io_Layer_StatusListening) {
00208     int rv;
00209     GWEN_SOCKET *newS=NULL;
00210     GWEN_INETADDRESS *iaddr=NULL;
00211 
00212     /* accept new connection (if there is any) */
00213     rv=GWEN_Socket_Accept(xio->socket, &iaddr, &newS);
00214     if (rv<0) {
00215       if (rv!=GWEN_ERROR_TIMEOUT && rv!=GWEN_ERROR_INTERRUPTED) {
00216         DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00217         GWEN_Io_Layer_SetStatus(io, GWEN_Io_Layer_StatusDisconnected);
00218         doneSomething=1;
00219       }
00220       /* still no incoming connection */
00221     }
00222     else {
00223       char addrBuffer[128];
00224       int port;
00225       GWEN_IO_LAYER *newIo;
00226 
00227       /* get peer address for logging */
00228       GWEN_InetAddr_GetAddress(iaddr, addrBuffer, sizeof(addrBuffer));
00229       port=GWEN_InetAddr_GetPort(iaddr);
00230       DBG_INFO(GWEN_LOGDOMAIN, "Incoming connection from %s (port %d)", addrBuffer, port);
00231 
00232       rv=GWEN_Socket_SetBlocking(newS, 0);
00233       if (rv) {
00234         DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00235         GWEN_Socket_Close(newS);
00236         GWEN_Socket_free(newS);
00237         GWEN_InetAddr_free(iaddr);
00238       }
00239       else {
00240         /* got a connection, set it up */
00241         newIo=GWEN_Io_LayerSocket_new(newS);
00242         GWEN_Io_LayerSocket_SetLocalAddr(newIo, xio->localAddr);
00243         GWEN_Io_LayerSocket_SetPeerAddr(newIo, iaddr);
00244         GWEN_InetAddr_free(iaddr);
00245         GWEN_Io_Layer_AddFlags(newIo,
00246                                GWEN_IO_LAYER_FLAGS_PASSIVE |
00247                                GWEN_IO_LAYER_FLAGS_TAKEOVER); /* take over new socket */
00248         GWEN_Io_Layer_SetStatus(newIo, GWEN_Io_Layer_StatusConnected);
00249 
00250         GWEN_Io_Layer_AddIncomingLayer(io, newIo);
00251       }
00252       doneSomething=1;
00253     }
00254   }
00255 
00256   return (doneSomething==0)?GWEN_Io_Layer_WorkResultBlocking:GWEN_Io_Layer_WorkResultOk;
00257 }
00258 
00259 
00260 
00261 GWEN_IO_LAYER_WORKRESULT GWEN_Io_LayerSocket_WorkOnRequests(GWEN_IO_LAYER *io) {
00262   GWEN_IO_LAYER_SOCKET *xio;
00263   int doneSomething=0;
00264 
00265   assert(io);
00266   xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_SOCKET, io);
00267   assert(xio);
00268 
00269   DBG_VERBOUS(GWEN_LOGDOMAIN, "LayerSocket: Working");
00270 
00271   /* work on connect request */
00272   if (xio->connectRequest) {
00273     int rv;
00274     GWEN_IO_REQUEST *r;
00275 
00276     r=xio->connectRequest;
00277     rv=GWEN_Socket_GetSocketError(xio->socket);
00278     if (rv<0) {
00279       if (rv!=GWEN_ERROR_TIMEOUT && rv!=GWEN_ERROR_INTERRUPTED) {
00280         DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00281         GWEN_Io_LayerSocket_AbortRequests(io, GWEN_ERROR_ABORTED);
00282         GWEN_Io_Layer_SetStatus(io, GWEN_Io_Layer_StatusDisconnected);
00283         doneSomething=1;
00284       }
00285       /* still not connected */
00286     }
00287     else {
00288       char addrBuffer[128];
00289       int port;
00290 
00291       /* get address for logging */
00292       GWEN_InetAddr_GetAddress(xio->peerAddr, addrBuffer, sizeof(addrBuffer));
00293       port=GWEN_InetAddr_GetPort(xio->peerAddr);
00294       /* connected */
00295       xio->connectRequest=NULL;
00296       GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, 0);
00297       GWEN_Io_Request_free(r);
00298       GWEN_Io_Layer_SetStatus(io, GWEN_Io_Layer_StatusConnected);
00299       DBG_INFO(GWEN_LOGDOMAIN, "Now connected to %s (port %d)", addrBuffer, port);
00300       doneSomething=1;
00301     }
00302   }
00303 
00304   /* work on read request */
00305   if (xio->readRequest) {
00306     ssize_t rv;
00307     int bytesRead;
00308     GWEN_IO_REQUEST *r;
00309 
00310     r=xio->readRequest;
00311     bytesRead=GWEN_Io_Request_GetBufferSize(r)-GWEN_Io_Request_GetBufferPos(r);
00312     rv=GWEN_Socket_Read(xio->socket,
00313                         (char*) GWEN_Io_Request_GetBufferPtr(r)+
00314                         GWEN_Io_Request_GetBufferPos(r),
00315                         &bytesRead);
00316     if (rv<0) {
00317       if (rv!=GWEN_ERROR_TIMEOUT && rv!=GWEN_ERROR_INTERRUPTED) {
00318         DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int)rv);
00319         xio->readRequest=NULL;
00320         GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_IO);
00321         GWEN_Io_Request_free(r);
00322         doneSomething=1;
00323       }
00324       /* nothing to read, nothing done, so we don't set doneSomething=1 here ! */
00325     }
00326     else {
00327       if (bytesRead==0) {
00328         /* end of stream reached */
00329         DBG_INFO(GWEN_LOGDOMAIN, "End of stream reached");
00330         xio->readRequest=NULL;
00331         GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_EOF);
00332         GWEN_Io_Request_free(r);
00333         doneSomething=1;
00334       }
00335       else {
00336         uint32_t newPos;
00337 
00338         /* some data returned */
00339         newPos=GWEN_Io_Request_GetBufferPos(r)+bytesRead;
00340         GWEN_Io_Request_SetBufferPos(r, newPos);
00341 
00342         if (newPos>=GWEN_Io_Request_GetBufferSize(r) ||
00343             !(GWEN_Io_Request_GetFlags(r) & GWEN_IO_REQUEST_FLAGS_READALL)) {
00344           xio->readRequest=NULL;
00345           GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, 0);
00346           GWEN_Io_Request_free(r);
00347           DBG_VERBOUS(GWEN_LOGDOMAIN, "Read request finished (read %d bytes)", newPos);
00348         }
00349         else {
00350           DBG_VERBOUS(GWEN_LOGDOMAIN, "Read request waiting (got %d bytes)", newPos);
00351         }
00352         doneSomething=1;
00353       }
00354     }
00355   }
00356 
00357   /* work on write request */
00358   if (xio->writeRequest) {
00359     int bytesWritten;
00360     GWEN_IO_REQUEST *r;
00361     int rv;
00362 
00363     r=xio->writeRequest;
00364     bytesWritten=GWEN_Io_Request_GetBufferSize(r)-GWEN_Io_Request_GetBufferPos(r);
00365     rv=GWEN_Socket_Write(xio->socket,
00366                          (const char*)GWEN_Io_Request_GetBufferPtr(r)+
00367                          GWEN_Io_Request_GetBufferPos(r),
00368                          &bytesWritten);
00369     if (rv<0) {
00370       if (rv!=GWEN_ERROR_TIMEOUT && rv!=GWEN_ERROR_INTERRUPTED) {
00371         DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00372         xio->writeRequest=NULL;
00373         GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_IO);
00374         GWEN_Io_Request_free(r);
00375         doneSomething=1;
00376       }
00377       /* nothing to read, nothing done, so we don't set doneSomething=1 here ! */
00378     }
00379     else {
00380       uint32_t newPos;
00381 
00382       /* some data returned */
00383       newPos=GWEN_Io_Request_GetBufferPos(r)+bytesWritten;
00384       GWEN_Io_Request_SetBufferPos(r, newPos);
00385 
00386       if (newPos>=GWEN_Io_Request_GetBufferSize(r) ||
00387           !(GWEN_Io_Request_GetFlags(r) & GWEN_IO_REQUEST_FLAGS_WRITEALL)) {
00388         /* request complete */
00389         xio->writeRequest=NULL;
00390         GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, 0);
00391         GWEN_Io_Request_free(r);
00392         DBG_INFO(GWEN_LOGDOMAIN, "Write request finished (%d bytes written)", newPos);
00393       }
00394       doneSomething=1;
00395     }
00396   }
00397 
00398   /* possibly check for incoming layers */
00399   if (GWEN_Io_LayerSocket_CheckForIncoming(io)!=GWEN_Io_Layer_WorkResultBlocking)
00400     doneSomething=1;
00401 
00402 
00403   return (doneSomething==0)?GWEN_Io_Layer_WorkResultBlocking:GWEN_Io_Layer_WorkResultOk;
00404 }
00405 
00406 
00407 
00408 int GWEN_Io_LayerSocket_AddRequest(GWEN_IO_LAYER *io, GWEN_IO_REQUEST *r) {
00409   GWEN_IO_LAYER_SOCKET *xio;
00410   GWEN_IO_LAYER_STATUS st;
00411   uint32_t lflags;
00412 
00413   assert(io);
00414   xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_SOCKET, io);
00415   assert(xio);
00416 
00417   st=GWEN_Io_Layer_GetStatus(io);
00418   lflags=GWEN_Io_Layer_GetFlags(io);
00419 
00420   switch(GWEN_Io_Request_GetType(r)) {
00421   case GWEN_Io_Request_TypeConnect:
00422     /* check status */
00423     if (st==GWEN_Io_Layer_StatusConnected &&
00424         (lflags & GWEN_IO_LAYER_FLAGS_PASSIVE)) {
00425       DBG_INFO(GWEN_LOGDOMAIN, "Socket already connected");
00426       GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, 0);
00427       return 0;
00428     }
00429     if (st!=GWEN_Io_Layer_StatusUnconnected &&
00430         st!=GWEN_Io_Layer_StatusDisconnected) {
00431       DBG_INFO(GWEN_LOGDOMAIN, "Socket is open");
00432       GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_INVALID);
00433       return GWEN_ERROR_NOT_OPEN;
00434     }
00435 
00436     /* check whether we already have a read request */
00437     if (xio->connectRequest) {
00438       DBG_INFO(GWEN_LOGDOMAIN, "There already is a connect request");
00439       GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_IN_PROGRESS);
00440       return GWEN_ERROR_IN_PROGRESS;
00441     }
00442     else {
00443       char addrBuffer[128];
00444       int port;
00445       int rv;
00446 
00447       /* get address for logging */
00448       GWEN_InetAddr_GetAddress(xio->peerAddr, addrBuffer, sizeof(addrBuffer));
00449       port=GWEN_InetAddr_GetPort(xio->peerAddr);
00450       DBG_INFO(GWEN_LOGDOMAIN, "Starting to connect to %s (port %d)", addrBuffer, port);
00451 
00452       /* not a passive io layer */
00453       GWEN_Io_Layer_SubFlags(io, GWEN_IO_LAYER_FLAGS_PASSIVE);
00454 
00455       /* open socket */
00456       rv=GWEN_Socket_Open(xio->socket);
00457       if (rv) {
00458         DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00459         GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, rv);
00460         return rv;
00461       }
00462 
00463 #ifndef HACK_FOR_DAVID
00464       /* set nonblocking */
00465       rv=GWEN_Socket_SetBlocking(xio->socket, 0);
00466       if (rv) {
00467         GWEN_Socket_Close(xio->socket);
00468         DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00469         GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, rv);
00470         return rv;
00471       }
00472 #endif
00473 
00474       /* actually start to connect */
00475       rv=GWEN_Socket_Connect(xio->socket, xio->peerAddr);
00476       /* not yet finished or real error ? */
00477       if (rv) {
00478         if (rv!=GWEN_ERROR_IN_PROGRESS) {
00479           /* real error, so return that error */
00480           DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00481           GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, rv);
00482         }
00483         else {
00484           /* enqueue request */
00485           xio->connectRequest=r;
00486           GWEN_Io_Request_Attach(xio->connectRequest);
00487           GWEN_Io_Layer_SetStatus(io, GWEN_Io_Layer_StatusConnecting);
00488         }
00489       }
00490       else {
00491 #ifdef HACK_FOR_DAVID
00492         /* set nonblocking */
00493         rv=GWEN_Socket_SetBlocking(xio->socket, 0);
00494         if (rv) {
00495           GWEN_Socket_Close(xio->socket);
00496           DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00497           GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, rv);
00498           return rv;
00499         }
00500 #endif
00501 
00502         /* connected */
00503         DBG_INFO(GWEN_LOGDOMAIN, "Immediately connected to %s (port %d)", addrBuffer, port);
00504         GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, 0);
00505         GWEN_Io_Layer_SetStatus(io, GWEN_Io_Layer_StatusConnected);
00506       }
00507     }
00508     break;
00509 
00510   case GWEN_Io_Request_TypeDisconnect:
00511     /* check status */
00512     if (st!=GWEN_Io_Layer_StatusConnected) {
00513       DBG_INFO(GWEN_LOGDOMAIN, "Io layer not connected");
00514       GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_NOT_OPEN);
00515       return GWEN_ERROR_NOT_OPEN;
00516     }
00517     else {
00518       if ((xio->readRequest==NULL && xio->writeRequest==NULL) ||
00519           (GWEN_Io_Request_GetFlags(r) & GWEN_IO_REQUEST_FLAGS_FORCE)) {
00520         /* close files if not forbidden */
00521         if (!(lflags & GWEN_IO_LAYER_FLAGS_DONTCLOSE))
00522           GWEN_Socket_Close(xio->socket);
00523         GWEN_Io_LayerSocket_AbortRequests(io, GWEN_ERROR_ABORTED);
00524 
00525         /* closed */
00526         GWEN_Io_Layer_SetStatus(io, GWEN_Io_Layer_StatusDisconnected);
00527         GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, 0);
00528       }
00529       else {
00530         /* still some pending operations, try again */
00531         return GWEN_ERROR_TRY_AGAIN;
00532       }
00533     }
00534     break;
00535 
00536   case GWEN_Io_Request_TypeRead:
00537     /* check status */
00538     if (st!=GWEN_Io_Layer_StatusConnected) {
00539       DBG_INFO(GWEN_LOGDOMAIN, "Socket is not open");
00540       GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_NOT_OPEN);
00541       return GWEN_ERROR_NOT_OPEN;
00542     }
00543 
00544     /* check whether we already have a read request */
00545     if (xio->readRequest) {
00546       DBG_INFO(GWEN_LOGDOMAIN, "There already is a read request");
00547       return GWEN_ERROR_TRY_AGAIN;
00548     }
00549 
00550     /* enqueue request */
00551     xio->readRequest=r;
00552     GWEN_Io_Request_Attach(xio->readRequest);
00553     break;
00554 
00555   case GWEN_Io_Request_TypeWrite:
00556     /* check status */
00557     if (st!=GWEN_Io_Layer_StatusConnected) {
00558       DBG_INFO(GWEN_LOGDOMAIN, "File is not open");
00559       GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_NOT_OPEN);
00560       return GWEN_ERROR_NOT_OPEN;
00561     }
00562 
00563     /* check whether we already have a write request */
00564     if (xio->writeRequest) {
00565       DBG_INFO(GWEN_LOGDOMAIN, "There already is a write request");
00566       return GWEN_ERROR_TRY_AGAIN;
00567     }
00568 
00569     /* enqueue request */
00570     xio->writeRequest=r;
00571     GWEN_Io_Request_Attach(xio->writeRequest);
00572     break;
00573 
00574   default:
00575     DBG_INFO(GWEN_LOGDOMAIN, "This request type is not supported (%d)", GWEN_Io_Request_GetType(r));
00576     GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_NOT_SUPPORTED);
00577     return GWEN_ERROR_NOT_SUPPORTED;
00578   }
00579 
00580   return 0;
00581 }
00582 
00583 
00584 
00585 int GWEN_Io_LayerSocket_DelRequest(GWEN_IO_LAYER *io, GWEN_IO_REQUEST *r) {
00586   GWEN_IO_LAYER_SOCKET *xio;
00587 
00588   assert(io);
00589   xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_SOCKET, io);
00590   assert(xio);
00591 
00592   switch(GWEN_Io_Request_GetType(r)) {
00593   case GWEN_Io_Request_TypeRead:
00594     if (xio->readRequest==r) {
00595       DBG_DEBUG(GWEN_LOGDOMAIN, "Aborted read request");
00596       xio->readRequest=NULL;
00597       GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_ABORTED);
00598       GWEN_Io_Request_free(r);
00599     }
00600     else {
00601       /* not my request */
00602       DBG_INFO(GWEN_LOGDOMAIN, "Read request not registered with this io layer");
00603       return GWEN_ERROR_INVALID;
00604     }
00605     break;
00606 
00607   case GWEN_Io_Request_TypeWrite:
00608     if (xio->writeRequest==r) {
00609       DBG_DEBUG(GWEN_LOGDOMAIN, "Aborted write request");
00610       xio->writeRequest=NULL;
00611       GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_ABORTED);
00612       GWEN_Io_Request_free(r);
00613     }
00614     else {
00615       /* not my request */
00616       DBG_INFO(GWEN_LOGDOMAIN, "Write request not registered with this io layer");
00617       return GWEN_ERROR_INVALID;
00618     }
00619     break;
00620 
00621   case GWEN_Io_Request_TypeConnect:
00622     if (xio->connectRequest==r) {
00623       DBG_DEBUG(GWEN_LOGDOMAIN, "Aborted connect request");
00624       if (!(GWEN_Io_Layer_GetFlags(io) & GWEN_IO_LAYER_FLAGS_DONTCLOSE))
00625         GWEN_Socket_Close(xio->socket);
00626       GWEN_Io_Layer_SetStatus(io, GWEN_Io_Layer_StatusDisconnected);
00627       GWEN_Io_LayerSocket_AbortRequests(io, GWEN_ERROR_ABORTED);
00628     }
00629     else {
00630       /* not my request */
00631       DBG_INFO(GWEN_LOGDOMAIN, "Read request not registered with this io layer");
00632       return GWEN_ERROR_INVALID;
00633     }
00634     break;
00635 
00636   default:
00637     break;
00638   }
00639 
00640   return 0;
00641 }
00642 
00643 
00644 
00645 int GWEN_Io_LayerSocket_HasWaitingRequests(GWEN_IO_LAYER *io) {
00646   GWEN_IO_LAYER_SOCKET *xio;
00647 
00648   assert(io);
00649   xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_SOCKET, io);
00650   assert(xio);
00651 
00652   if (xio->readRequest || xio->writeRequest || xio->connectRequest)
00653     return 1;
00654   else
00655     return 0;
00656 }
00657 
00658 
00659 
00660 int GWEN_Io_LayerSocket_AddWaitingSockets(GWEN_IO_LAYER *io,
00661                                           GWEN_SOCKET_LIST2 *readSockets,
00662                                           GWEN_SOCKET_LIST2 *writeSockets) {
00663   GWEN_IO_LAYER_SOCKET *xio;
00664 
00665   assert(io);
00666   xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_SOCKET, io);
00667   assert(xio);
00668 
00669   if (xio->readRequest || GWEN_Io_Layer_GetStatus(io)==GWEN_Io_Layer_StatusListening)
00670     GWEN_Socket_List2_PushBack(readSockets, xio->socket);
00671   if (xio->writeRequest || xio->connectRequest)
00672     GWEN_Socket_List2_PushBack(writeSockets, xio->socket);
00673 
00674   return 0;
00675 }
00676 
00677 
00678 
00679 int GWEN_Io_LayerSocket_Listen(GWEN_IO_LAYER *io) {
00680   GWEN_IO_LAYER_SOCKET *xio;
00681   char addrBuffer[128];
00682   int port;
00683   int rv;
00684 
00685   assert(io);
00686   xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_SOCKET, io);
00687   assert(xio);
00688 
00689   /* get address for logging */
00690   GWEN_InetAddr_GetAddress(xio->localAddr, addrBuffer, sizeof(addrBuffer));
00691   port=GWEN_InetAddr_GetPort(xio->localAddr);
00692 
00693   /* open socket */
00694   rv=GWEN_Socket_Open(xio->socket);
00695   if (rv) {
00696     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00697     return rv;
00698   }
00699   
00700   /* set nonblocking */
00701   rv=GWEN_Socket_SetBlocking(xio->socket, 0);
00702   if (rv) {
00703     GWEN_Socket_Close(xio->socket);
00704     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00705     return rv;
00706   }
00707 
00708   /* allow reuse of addresses */
00709   rv=GWEN_Socket_SetReuseAddress(xio->socket, 1);
00710   if (rv) {
00711     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00712   }
00713 
00714   /* bind socket to local address */
00715   rv=GWEN_Socket_Bind(xio->socket, xio->localAddr);
00716   if (rv) {
00717     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00718     return rv;
00719   }
00720 
00721   /* start listening */
00722   DBG_NOTICE(GWEN_LOGDOMAIN, "Starting to listen on %s (port %d)", addrBuffer, port);
00723   rv=GWEN_Socket_Listen(xio->socket, 10);
00724   if (rv) {
00725     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00726     return rv;
00727   }
00728 
00729   GWEN_Io_Layer_SetStatus(io, GWEN_Io_Layer_StatusListening);
00730 
00731   return 0;
00732 }
00733 
00734 
00735 
00736 
00737 
00738 
00739 
00740 
00741 
00742 
00743 
00744 
00745 

Generated on Wed Jul 9 13:12:28 2008 for gwenhywfar by  doxygen 1.5.6