00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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>
00028
00029 #include <assert.h>
00030 #include <errno.h>
00031 #include <string.h>
00032 #include <unistd.h>
00033 #include <fcntl.h>
00034
00035
00036
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
00085 if (!(lflags & GWEN_IO_LAYER_FLAGS_DONTCLOSE))
00086 GWEN_Socket_Close(xio->socket);
00087
00088
00089 if (lflags & GWEN_IO_LAYER_FLAGS_TAKEOVER) {
00090 GWEN_Socket_free(xio->socket);
00091 xio->socket=(GWEN_SOCKET*) -1;
00092 }
00093
00094
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
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
00221 }
00222 else {
00223 char addrBuffer[128];
00224 int port;
00225 GWEN_IO_LAYER *newIo;
00226
00227
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
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);
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
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
00286 }
00287 else {
00288 char addrBuffer[128];
00289 int port;
00290
00291
00292 GWEN_InetAddr_GetAddress(xio->peerAddr, addrBuffer, sizeof(addrBuffer));
00293 port=GWEN_InetAddr_GetPort(xio->peerAddr);
00294
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
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
00325 }
00326 else {
00327 if (bytesRead==0) {
00328
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
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
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
00378 }
00379 else {
00380 uint32_t newPos;
00381
00382
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
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
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
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
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
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
00453 GWEN_Io_Layer_SubFlags(io, GWEN_IO_LAYER_FLAGS_PASSIVE);
00454
00455
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
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
00475 rv=GWEN_Socket_Connect(xio->socket, xio->peerAddr);
00476
00477 if (rv) {
00478 if (rv!=GWEN_ERROR_IN_PROGRESS) {
00479
00480 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00481 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, rv);
00482 }
00483 else {
00484
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
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
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
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
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
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
00531 return GWEN_ERROR_TRY_AGAIN;
00532 }
00533 }
00534 break;
00535
00536 case GWEN_Io_Request_TypeRead:
00537
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
00545 if (xio->readRequest) {
00546 DBG_INFO(GWEN_LOGDOMAIN, "There already is a read request");
00547 return GWEN_ERROR_TRY_AGAIN;
00548 }
00549
00550
00551 xio->readRequest=r;
00552 GWEN_Io_Request_Attach(xio->readRequest);
00553 break;
00554
00555 case GWEN_Io_Request_TypeWrite:
00556
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
00564 if (xio->writeRequest) {
00565 DBG_INFO(GWEN_LOGDOMAIN, "There already is a write request");
00566 return GWEN_ERROR_TRY_AGAIN;
00567 }
00568
00569
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
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
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
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
00690 GWEN_InetAddr_GetAddress(xio->localAddr, addrBuffer, sizeof(addrBuffer));
00691 port=GWEN_InetAddr_GetPort(xio->localAddr);
00692
00693
00694 rv=GWEN_Socket_Open(xio->socket);
00695 if (rv) {
00696 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00697 return rv;
00698 }
00699
00700
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
00709 rv=GWEN_Socket_SetReuseAddress(xio->socket, 1);
00710 if (rv) {
00711 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00712 }
00713
00714
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
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