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 #include <gwenhywfar/url.h>
00027
00028 #include <gwenhywfar/text.h>
00029 #include <gwenhywfar/base64.h>
00030
00031 #include <assert.h>
00032 #include <errno.h>
00033 #include <string.h>
00034 #include <unistd.h>
00035 #include <fcntl.h>
00036
00037
00038 #define GWEN_PROXY_ENVVAR "GWEN_PROXY"
00039
00040
00041
00042 GWEN_INHERIT(GWEN_IO_LAYER, GWEN_IO_LAYER_SOCKET)
00043
00044
00045
00046 int GWEN_Proxy_Connect(GWEN_SOCKET *sp,
00047 const GWEN_INETADDRESS *addr,
00048 uint32_t guiid) {
00049 const char *s;
00050
00051
00052 if (GWEN_Socket_GetSocketType(sp)!=GWEN_SocketTypeTCP)
00053 return GWEN_Socket_Connect(sp, addr);
00054
00055 s=getenv(GWEN_PROXY_ENVVAR);
00056 if (s && *s) {
00057 GWEN_URL *url;
00058 GWEN_BUFFER *sendBuf;
00059 int tport;
00060 char taddr[64];
00061 char numbuf[16];
00062 const char *t;
00063 int rv;
00064 GWEN_INETADDRESS *in;
00065 int ok=0;
00066 int first=1;
00067 int len;
00068 int idx=0;
00069 char wrk[1024];
00070
00071 url=GWEN_Url_fromString(s);
00072 if (url==NULL) {
00073 DBG_ERROR(GWEN_LOGDOMAIN, "Bad string for proxy [%s]", s);
00074 return GWEN_ERROR_IO;
00075 }
00076
00077 sendBuf=GWEN_Buffer_new(0, 256, 0, 1);
00078
00079
00080 GWEN_Buffer_AppendString(sendBuf, "CONNECT ");
00081
00082 tport=GWEN_InetAddr_GetPort(addr);
00083 GWEN_InetAddr_GetAddress(addr, taddr, sizeof(taddr));
00084
00085 GWEN_Buffer_AppendString(sendBuf, taddr);
00086 GWEN_Buffer_AppendString(sendBuf, ":");
00087 snprintf(numbuf, sizeof(numbuf)-1, "%d", tport);
00088 numbuf[sizeof(numbuf)-1]=0;
00089 GWEN_Buffer_AppendString(sendBuf, numbuf);
00090
00091 GWEN_Buffer_AppendString(sendBuf, " HTTP/1.1\r\n");
00092
00093
00094 GWEN_Buffer_AppendString(sendBuf, "Host: ");
00095 GWEN_Buffer_AppendString(sendBuf, taddr);
00096 GWEN_Buffer_AppendString(sendBuf, ":");
00097 GWEN_Buffer_AppendString(sendBuf, numbuf);
00098 GWEN_Buffer_AppendString(sendBuf, "\r\n");
00099
00100
00101 t=GWEN_Url_GetUserName(url);
00102 if (t && *t) {
00103 GWEN_BUFFER *abuf;
00104
00105
00106 abuf=GWEN_Buffer_new(0, 64, 0, 1);
00107 GWEN_Buffer_AppendString(sendBuf, "Proxy-Authorization: Basic ");
00108
00109 GWEN_Buffer_AppendString(abuf, t);
00110 t=GWEN_Url_GetPassword(url);
00111 if (t && *t) {
00112 GWEN_Buffer_AppendString(abuf, ":");
00113 GWEN_Buffer_AppendString(abuf, t);
00114 }
00115
00116 rv=GWEN_Base64_Encode((const unsigned char*) GWEN_Buffer_GetStart(abuf),
00117 GWEN_Buffer_GetUsedBytes(abuf),
00118 sendBuf, 0);
00119 if (rv<0) {
00120 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00121 GWEN_Buffer_free(abuf);
00122 GWEN_Buffer_free(sendBuf);
00123 GWEN_Url_free(url);
00124 return rv;
00125 }
00126 GWEN_Buffer_free(abuf);
00127 GWEN_Buffer_AppendString(sendBuf, "\r\n");
00128 }
00129
00130
00131 GWEN_Buffer_AppendString(sendBuf, "\r\n");
00132
00133
00134 DBG_ERROR(0, "Would send this:");
00135 GWEN_Buffer_Dump(sendBuf, stderr, 2);
00136
00137
00138 in=GWEN_InetAddr_new(GWEN_AddressFamilyIP);
00139 assert(in);
00140
00141 rv=GWEN_InetAddr_SetPort(in, GWEN_Url_GetPort(url));
00142 if (rv<0) {
00143 GWEN_InetAddr_free(in);
00144 GWEN_Buffer_free(sendBuf);
00145 GWEN_Url_free(url);
00146 return rv;
00147 }
00148
00149 rv=GWEN_InetAddr_SetAddress(in, GWEN_Url_GetServer(url));
00150 if (rv) {
00151 if (rv==GWEN_ERROR_BAD_ADDRESS) {
00152 rv=GWEN_InetAddr_SetName(in, GWEN_Url_GetServer(url));
00153 if (rv) {
00154 GWEN_InetAddr_free(in);
00155 GWEN_Buffer_free(sendBuf);
00156 GWEN_Url_free(url);
00157 return rv;
00158 }
00159 }
00160 else {
00161 GWEN_InetAddr_free(in);
00162 GWEN_Buffer_free(sendBuf);
00163 GWEN_Url_free(url);
00164 return rv;
00165 }
00166 }
00167 GWEN_Url_free(url);
00168
00169
00170
00171
00172
00173 rv=GWEN_Socket_SetBlocking(sp, 1);
00174 if (rv) {
00175 GWEN_InetAddr_free(in);
00176 GWEN_Buffer_free(sendBuf);
00177 return rv;
00178 }
00179
00180 tport=GWEN_InetAddr_GetPort(in);
00181 GWEN_InetAddr_GetAddress(in, taddr, sizeof(taddr));
00182 DBG_INFO(GWEN_LOGDOMAIN, "Connecting to proxy %s (port %d)", taddr, tport);
00183 if (1) {
00184 char dbuf[256];
00185
00186 snprintf(dbuf, sizeof(dbuf)-1, I18N("Connecting to proxy %s (port %d)"), taddr, tport);
00187 dbuf[sizeof(dbuf)-1]=0;
00188 GWEN_Gui_ProgressLog(guiid, GWEN_LoggerLevel_Info, dbuf);
00189 }
00190
00191
00192 rv=GWEN_Socket_Connect(sp, in);
00193 GWEN_InetAddr_free(in);
00194 if (rv) {
00195 if (rv==GWEN_ERROR_IN_PROGRESS) {
00196 rv=GWEN_Socket_WaitForWrite(sp, 10000);
00197 if (rv) {
00198 DBG_INFO(GWEN_LOGDOMAIN, "Error connecting to proxy (%d)", rv);
00199 GWEN_Buffer_free(sendBuf);
00200 return rv;
00201 }
00202 }
00203 else {
00204 DBG_INFO(GWEN_LOGDOMAIN, "Error connecting to proxy (%d)", rv);
00205 GWEN_Buffer_free(sendBuf);
00206 return rv;
00207 }
00208 }
00209
00210
00211 first=1;
00212 if (1) {
00213 const char *p;
00214
00215 len=GWEN_Buffer_GetUsedBytes(sendBuf);
00216 p=GWEN_Buffer_GetStart(sendBuf);
00217 while(len) {
00218 int rl;
00219
00220 rv=GWEN_Socket_WaitForWrite(sp, first?40000:1000);
00221 if (rv) {
00222 DBG_INFO(GWEN_LOGDOMAIN, "Error writing to proxy (%d)", rv);
00223 GWEN_Buffer_free(sendBuf);
00224 return rv;
00225 }
00226
00227 first=0;
00228
00229 rl=len;
00230 rv=GWEN_Socket_Write(sp, p, &rl);
00231 if (rv<0) {
00232 DBG_INFO(GWEN_LOGDOMAIN, "Error writing to proxy (%d)", rv);
00233 GWEN_Buffer_free(sendBuf);
00234 return rv;
00235 }
00236 if (rl<1) {
00237 DBG_INFO(GWEN_LOGDOMAIN, "Zero bytes written to proxy, aborting");
00238 GWEN_Buffer_free(sendBuf);
00239 return GWEN_ERROR_IO;
00240 }
00241 p+=rl;
00242 len-=rl;
00243 }
00244 }
00245 GWEN_Buffer_free(sendBuf);
00246
00247
00248 first=1;
00249 while (1) {
00250 rv=GWEN_Socket_WaitForRead(sp, first?40000:1000);
00251 if (rv) {
00252 DBG_INFO(GWEN_LOGDOMAIN, "Error reading from proxy (%d)", rv);
00253 return rv;
00254 }
00255
00256 first=0;
00257 len=1;
00258 rv=GWEN_Socket_Read(sp, wrk+idx, &len);
00259 if (rv) {
00260 DBG_INFO(GWEN_LOGDOMAIN, "Error reading from proxy (%d)", rv);
00261 return rv;
00262 }
00263
00264 if(wrk[idx]=='\r')
00265 continue;
00266
00267 if (wrk[idx]=='\n') {
00268 if (!idx) {
00269
00270 if (ok) {
00271 DBG_INFO(GWEN_LOGDOMAIN, "Proxy accepted CONNECT request, EOLN met");
00272 GWEN_Gui_ProgressLog(guiid, GWEN_LoggerLevel_Info, I18N("Proxy accepted CONNECT request."));
00273 return 0;
00274 }
00275 else {
00276 DBG_INFO(GWEN_LOGDOMAIN, "Emtpy line end, unknown proxy status");
00277 return GWEN_ERROR_IO;
00278 }
00279 }
00280
00281 if (!ok) {
00282 wrk[idx]=0;
00283 if (strncmp(wrk, "HTTP/1.0 200", 12)==0 ||
00284 strncmp(wrk, "HTTP/1.1 200", 12)==0)
00285 ok=1;
00286 else {
00287 DBG_ERROR(GWEN_LOGDOMAIN, "Proxy rejected CONNECT request: %s", wrk);
00288 if (1) {
00289 GWEN_BUFFER *dbuf;
00290
00291 dbuf=GWEN_Buffer_new(0, 256, 0, 1);
00292 GWEN_Buffer_AppendString(dbuf, I18N("Proxy rejected CONNECT request: "));
00293 GWEN_Buffer_AppendString(dbuf, wrk);
00294 GWEN_Gui_ProgressLog(guiid, GWEN_LoggerLevel_Info, GWEN_Buffer_GetStart(dbuf));
00295 GWEN_Buffer_free(dbuf);
00296 }
00297 return GWEN_ERROR_IO;
00298 }
00299 }
00300 idx=0;
00301 }
00302 else if (++idx==sizeof(wrk))
00303 return GWEN_ERROR_IO;
00304 }
00305 }
00306 else
00307 return GWEN_Socket_Connect(sp, addr);
00308 }
00309
00310
00311
00312 #if 0
00313 int GWEN_Proxy_Connect(GWEN_SOCKET *sp, const GWEN_INETADDRESS *addr) {
00314 int err;
00315 int tport;
00316 int len;
00317 int idx=0;
00318 int ok=0;
00319 int first=1;
00320 char *proxy;
00321 char *port;
00322 GWEN_INETADDRESS *in;
00323 char taddr[64];
00324 char wrk[1024];
00325
00326 if (GWEN_Socket_GetSocketType(sp)!=GWEN_SocketTypeTCP)
00327 return GWEN_Socket_Connect(sp, addr);
00328
00329 tport=GWEN_InetAddr_GetPort(addr);
00330 GWEN_InetAddr_GetAddress(addr, taddr, sizeof(taddr));
00331 snprintf(wrk, sizeof(wrk)-1, "CONNECT %s:%d\n", taddr, tport);
00332 wrk[sizeof(wrk)-1]=0;
00333 len=strlen(wrk);
00334
00335 port=proxy=strdup(getenv("GWEN_PROXY"));
00336 assert(port);
00337
00338 while (*port) {
00339 if (*port==':') {
00340 *port++=0;
00341 break;
00342 }
00343 else
00344 port++;
00345 }
00346
00347 if (!*port) {
00348 free(proxy);
00349 return GWEN_ERROR_BAD_ADDRESS;
00350 }
00351
00352 in=GWEN_InetAddr_new(GWEN_AddressFamilyIP);
00353 assert(in);
00354
00355 err=GWEN_InetAddr_SetPort(in, atoi(port));
00356 if (err) {
00357 free(proxy);
00358 GWEN_InetAddr_free(in);
00359 return err;
00360 }
00361
00362 err=GWEN_InetAddr_SetAddress(in, proxy);
00363 if (err) {
00364 if (err==GWEN_ERROR_BAD_ADDRESS) {
00365 err=GWEN_InetAddr_SetName(in, proxy);
00366 if (err) {
00367 free(proxy);
00368 GWEN_InetAddr_free(in);
00369 return err;
00370 }
00371 }
00372 else {
00373 free(proxy);
00374 GWEN_InetAddr_free(in);
00375 return err;
00376 }
00377 }
00378
00379 free(proxy);
00380
00381
00382
00383
00384
00385 err=GWEN_Socket_SetBlocking(sp, 1);
00386 if (err) {
00387 GWEN_InetAddr_free(in);
00388 return err;
00389 }
00390
00391 tport=GWEN_InetAddr_GetPort(in);
00392 GWEN_InetAddr_GetAddress(in, taddr, sizeof(taddr));
00393 DBG_INFO(GWEN_LOGDOMAIN, "Connecting to proxy %s (port %d)", taddr, tport);
00394
00395
00396 err=GWEN_Socket_Connect(sp, in);
00397 GWEN_InetAddr_free(in);
00398 if (err) {
00399 if (err==GWEN_ERROR_IN_PROGRESS) {
00400 err=GWEN_Socket_WaitForWrite(sp, 10000);
00401 if (err)
00402 return err;
00403 }
00404 else
00405 return err;
00406 }
00407
00408
00409 err=GWEN_Socket_Write(sp, wrk, &len);
00410 if (err)
00411 return err;
00412
00413 while (1) {
00414 err=GWEN_Socket_WaitForRead(sp, first?40000:1000);
00415 if (err)
00416 return err;
00417
00418 first=0;
00419 len=1;
00420 err=GWEN_Socket_Read(sp, wrk+idx, &len);
00421 if (err)
00422 return err;
00423
00424 if(wrk[idx]=='\r')
00425 continue;
00426
00427 if(wrk[idx]=='\n') {
00428 if (!idx) {
00429 if (ok)
00430 return 0;
00431 else
00432 return GWEN_ERROR_IO;
00433 }
00434
00435 if(!ok) {
00436 wrk[idx]=0;
00437 if (strncmp(wrk, "HTTP/1.0 200", 12)==0 ||
00438 strncmp(wrk, "HTTP/1.1 200", 12)==0)
00439 ok=1;
00440 else
00441 return GWEN_ERROR_IO;
00442 }
00443
00444 idx=0;
00445 }
00446 else if (++idx==sizeof(wrk))
00447 return GWEN_ERROR_IO;
00448 }
00449 }
00450 #endif
00451
00452
00453
00454 GWEN_IO_LAYER *GWEN_Io_LayerSocket_new(GWEN_SOCKET *sk) {
00455 GWEN_IO_LAYER *io;
00456 GWEN_IO_LAYER_SOCKET *xio;
00457
00458 io=GWEN_Io_Layer_new(GWEN_IO_LAYER_SOCKET_TYPE, NULL);
00459 assert(io);
00460 GWEN_NEW_OBJECT(GWEN_IO_LAYER_SOCKET, xio);
00461 assert(xio);
00462 GWEN_INHERIT_SETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_SOCKET, io, xio, GWEN_Io_LayerSocket_freeData);
00463
00464 GWEN_Io_Layer_SetWorkOnRequestsFn(io, GWEN_Io_LayerSocket_WorkOnRequests);
00465 GWEN_Io_Layer_SetAddRequestFn(io, GWEN_Io_LayerSocket_AddRequest);
00466 GWEN_Io_Layer_SetDelRequestFn(io, GWEN_Io_LayerSocket_DelRequest);
00467 GWEN_Io_Layer_SetHasWaitingRequestsFn(io, GWEN_Io_LayerSocket_HasWaitingRequests);
00468 GWEN_Io_Layer_SetAddWaitingSocketsFn(io, GWEN_Io_LayerSocket_AddWaitingSockets);
00469 GWEN_Io_Layer_SetListenFn(io, GWEN_Io_LayerSocket_Listen);
00470
00471 xio->socket=sk;
00472
00473 GWEN_Io_Layer_SetStatus(io, GWEN_Io_Layer_StatusUnconnected);
00474
00475
00476 return io;
00477 }
00478
00479
00480
00481 GWENHYWFAR_CB
00482 void GWEN_Io_LayerSocket_freeData(void *bp, void *p) {
00483 GWEN_IO_LAYER *io;
00484 GWEN_IO_LAYER_SOCKET *xio;
00485 uint32_t lflags;
00486
00487 io=(GWEN_IO_LAYER*) bp;
00488 assert(io);
00489 xio=(GWEN_IO_LAYER_SOCKET*) p;
00490 assert(xio);
00491
00492 GWEN_Io_LayerSocket_AbortRequests(io, GWEN_ERROR_ABORTED);
00493 lflags=GWEN_Io_Layer_GetFlags(io);
00494
00495
00496 if (!(lflags & GWEN_IO_LAYER_FLAGS_DONTCLOSE))
00497 GWEN_Socket_Close(xio->socket);
00498
00499
00500 if (lflags & GWEN_IO_LAYER_FLAGS_TAKEOVER) {
00501 GWEN_Socket_free(xio->socket);
00502 xio->socket=(GWEN_SOCKET*) -1;
00503 }
00504
00505
00506 GWEN_FREE_OBJECT(xio);
00507 }
00508
00509
00510
00511 GWEN_INETADDRESS *GWEN_Io_LayerSocket_GetLocalAddr(const GWEN_IO_LAYER *io) {
00512 GWEN_IO_LAYER_SOCKET *xio;
00513
00514 assert(io);
00515 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_SOCKET, io);
00516 assert(xio);
00517
00518 return xio->localAddr;
00519 }
00520
00521
00522
00523 void GWEN_Io_LayerSocket_SetLocalAddr(GWEN_IO_LAYER *io, const GWEN_INETADDRESS *addr) {
00524 GWEN_IO_LAYER_SOCKET *xio;
00525
00526 assert(io);
00527 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_SOCKET, io);
00528 assert(xio);
00529
00530 GWEN_InetAddr_free(xio->localAddr);
00531 if (addr) xio->localAddr=GWEN_InetAddr_dup(addr);
00532 else xio->localAddr=NULL;
00533 }
00534
00535
00536
00537 GWEN_INETADDRESS *GWEN_Io_LayerSocket_GetPeerAddr(const GWEN_IO_LAYER *io) {
00538 GWEN_IO_LAYER_SOCKET *xio;
00539
00540 assert(io);
00541 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_SOCKET, io);
00542 assert(xio);
00543
00544 return xio->peerAddr;
00545 }
00546
00547
00548
00549 void GWEN_Io_LayerSocket_SetPeerAddr(GWEN_IO_LAYER *io, const GWEN_INETADDRESS *addr) {
00550 GWEN_IO_LAYER_SOCKET *xio;
00551
00552 assert(io);
00553 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_SOCKET, io);
00554 assert(xio);
00555
00556 GWEN_InetAddr_free(xio->peerAddr);
00557 if (addr) xio->peerAddr=GWEN_InetAddr_dup(addr);
00558 else xio->peerAddr=NULL;
00559 }
00560
00561
00562
00563 GWEN_SOCKET *GWEN_Io_LayerSocket_GetSocket(const GWEN_IO_LAYER *io) {
00564 GWEN_IO_LAYER_SOCKET *xio;
00565
00566 assert(io);
00567 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_SOCKET, io);
00568 assert(xio);
00569
00570 return xio->socket;
00571 }
00572
00573
00574
00575 void GWEN_Io_LayerSocket_AbortRequests(GWEN_IO_LAYER *io, int errorCode) {
00576 GWEN_IO_LAYER_SOCKET *xio;
00577
00578 assert(io);
00579 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_SOCKET, io);
00580 assert(xio);
00581
00582 if (xio->connectRequest) {
00583 GWEN_IO_REQUEST *r;
00584
00585 r=xio->connectRequest;
00586 xio->connectRequest=NULL;
00587 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, errorCode);
00588 GWEN_Io_Request_free(r);
00589 }
00590 if (xio->readRequest) {
00591 GWEN_IO_REQUEST *r;
00592
00593 r=xio->readRequest;
00594 xio->readRequest=NULL;
00595 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, errorCode);
00596 GWEN_Io_Request_free(r);
00597 }
00598 if (xio->writeRequest) {
00599 GWEN_IO_REQUEST *r;
00600
00601 r=xio->writeRequest;
00602 xio->writeRequest=NULL;
00603 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, errorCode);
00604 GWEN_Io_Request_free(r);
00605 }
00606 }
00607
00608
00609
00610 GWEN_IO_LAYER_WORKRESULT GWEN_Io_LayerSocket_CheckForIncoming(GWEN_IO_LAYER *io) {
00611 GWEN_IO_LAYER_SOCKET *xio;
00612 int doneSomething=0;
00613
00614 assert(io);
00615 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_SOCKET, io);
00616 assert(xio);
00617
00618 if (GWEN_Io_Layer_GetStatus(io)==GWEN_Io_Layer_StatusListening) {
00619 int rv;
00620 GWEN_SOCKET *newS=NULL;
00621 GWEN_INETADDRESS *iaddr=NULL;
00622
00623
00624 rv=GWEN_Socket_Accept(xio->socket, &iaddr, &newS);
00625 if (rv<0) {
00626 if (rv!=GWEN_ERROR_TIMEOUT && rv!=GWEN_ERROR_INTERRUPTED) {
00627 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00628 GWEN_Io_Layer_SetStatus(io, GWEN_Io_Layer_StatusDisconnected);
00629 doneSomething=1;
00630 }
00631
00632 }
00633 else {
00634 char addrBuffer[128];
00635 int port;
00636 GWEN_IO_LAYER *newIo;
00637
00638
00639 GWEN_InetAddr_GetAddress(iaddr, addrBuffer, sizeof(addrBuffer));
00640 port=GWEN_InetAddr_GetPort(iaddr);
00641 DBG_INFO(GWEN_LOGDOMAIN, "Incoming connection from %s (port %d)", addrBuffer, port);
00642
00643 rv=GWEN_Socket_SetBlocking(newS, 0);
00644 if (rv) {
00645 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00646 GWEN_Socket_Close(newS);
00647 GWEN_Socket_free(newS);
00648 GWEN_InetAddr_free(iaddr);
00649 }
00650 else {
00651
00652 newIo=GWEN_Io_LayerSocket_new(newS);
00653 GWEN_Io_LayerSocket_SetLocalAddr(newIo, xio->localAddr);
00654 GWEN_Io_LayerSocket_SetPeerAddr(newIo, iaddr);
00655 GWEN_InetAddr_free(iaddr);
00656 GWEN_Io_Layer_AddFlags(newIo,
00657 GWEN_IO_LAYER_FLAGS_PASSIVE |
00658 GWEN_IO_LAYER_FLAGS_TAKEOVER);
00659 GWEN_Io_Layer_SetStatus(newIo, GWEN_Io_Layer_StatusConnected);
00660
00661 GWEN_Io_Layer_AddIncomingLayer(io, newIo);
00662 }
00663 doneSomething=1;
00664 }
00665 }
00666
00667 return (doneSomething==0)?GWEN_Io_Layer_WorkResultBlocking:GWEN_Io_Layer_WorkResultOk;
00668 }
00669
00670
00671
00672 GWEN_IO_LAYER_WORKRESULT GWEN_Io_LayerSocket_WorkOnRequests(GWEN_IO_LAYER *io) {
00673 GWEN_IO_LAYER_SOCKET *xio;
00674 int doneSomething=0;
00675
00676 assert(io);
00677 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_SOCKET, io);
00678 assert(xio);
00679
00680 DBG_VERBOUS(GWEN_LOGDOMAIN, "LayerSocket: Working");
00681
00682
00683 if (xio->connectRequest) {
00684 int rv;
00685 GWEN_IO_REQUEST *r;
00686
00687 r=xio->connectRequest;
00688 rv=GWEN_Socket_GetSocketError(xio->socket);
00689 if (rv<0) {
00690 if (rv!=GWEN_ERROR_TIMEOUT && rv!=GWEN_ERROR_INTERRUPTED) {
00691 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00692 GWEN_Io_LayerSocket_AbortRequests(io, GWEN_ERROR_ABORTED);
00693 GWEN_Io_Layer_SetStatus(io, GWEN_Io_Layer_StatusDisconnected);
00694 doneSomething=1;
00695 }
00696
00697 }
00698 else {
00699 char addrBuffer[128];
00700 int port;
00701
00702
00703 GWEN_InetAddr_GetAddress(xio->peerAddr, addrBuffer, sizeof(addrBuffer));
00704 port=GWEN_InetAddr_GetPort(xio->peerAddr);
00705
00706 xio->connectRequest=NULL;
00707 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, 0);
00708 GWEN_Io_Request_free(r);
00709 GWEN_Io_Layer_SetStatus(io, GWEN_Io_Layer_StatusConnected);
00710 DBG_INFO(GWEN_LOGDOMAIN, "Now connected to %s (port %d)", addrBuffer, port);
00711 doneSomething=1;
00712 }
00713 }
00714
00715
00716 if (xio->readRequest) {
00717 ssize_t rv;
00718 int bytesRead;
00719 GWEN_IO_REQUEST *r;
00720
00721 r=xio->readRequest;
00722 bytesRead=GWEN_Io_Request_GetBufferSize(r)-GWEN_Io_Request_GetBufferPos(r);
00723 rv=GWEN_Socket_Read(xio->socket,
00724 (char*) GWEN_Io_Request_GetBufferPtr(r)+
00725 GWEN_Io_Request_GetBufferPos(r),
00726 &bytesRead);
00727 if (rv<0) {
00728 if (rv!=GWEN_ERROR_TIMEOUT && rv!=GWEN_ERROR_INTERRUPTED) {
00729 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int)rv);
00730 xio->readRequest=NULL;
00731 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_IO);
00732 GWEN_Io_Request_free(r);
00733 doneSomething=1;
00734 }
00735
00736 }
00737 else {
00738 if (bytesRead==0) {
00739
00740 DBG_INFO(GWEN_LOGDOMAIN, "End of stream reached");
00741 xio->readRequest=NULL;
00742 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_EOF);
00743 GWEN_Io_Request_free(r);
00744 doneSomething=1;
00745 }
00746 else {
00747 uint32_t newPos;
00748
00749
00750 newPos=GWEN_Io_Request_GetBufferPos(r)+bytesRead;
00751 GWEN_Io_Request_SetBufferPos(r, newPos);
00752
00753 if (newPos>=GWEN_Io_Request_GetBufferSize(r) ||
00754 !(GWEN_Io_Request_GetFlags(r) & GWEN_IO_REQUEST_FLAGS_READALL)) {
00755 xio->readRequest=NULL;
00756 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, 0);
00757 GWEN_Io_Request_free(r);
00758 DBG_VERBOUS(GWEN_LOGDOMAIN, "Read request finished (read %d bytes)", newPos);
00759 }
00760 else {
00761 DBG_VERBOUS(GWEN_LOGDOMAIN, "Read request waiting (got %d bytes)", newPos);
00762 }
00763 doneSomething=1;
00764 }
00765 }
00766 }
00767
00768
00769 if (xio->writeRequest) {
00770 int bytesWritten;
00771 GWEN_IO_REQUEST *r;
00772 int rv;
00773
00774 r=xio->writeRequest;
00775 bytesWritten=GWEN_Io_Request_GetBufferSize(r)-GWEN_Io_Request_GetBufferPos(r);
00776 rv=GWEN_Socket_Write(xio->socket,
00777 (const char*)GWEN_Io_Request_GetBufferPtr(r)+
00778 GWEN_Io_Request_GetBufferPos(r),
00779 &bytesWritten);
00780 if (rv<0) {
00781 if (rv!=GWEN_ERROR_TIMEOUT && rv!=GWEN_ERROR_INTERRUPTED) {
00782 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00783 xio->writeRequest=NULL;
00784 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_IO);
00785 GWEN_Io_Request_free(r);
00786 doneSomething=1;
00787 }
00788
00789 }
00790 else {
00791 uint32_t newPos;
00792
00793
00794 newPos=GWEN_Io_Request_GetBufferPos(r)+bytesWritten;
00795 GWEN_Io_Request_SetBufferPos(r, newPos);
00796
00797 if (newPos>=GWEN_Io_Request_GetBufferSize(r) ||
00798 !(GWEN_Io_Request_GetFlags(r) & GWEN_IO_REQUEST_FLAGS_WRITEALL)) {
00799
00800 xio->writeRequest=NULL;
00801 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, 0);
00802 GWEN_Io_Request_free(r);
00803 DBG_INFO(GWEN_LOGDOMAIN, "Write request finished (%d bytes written)", newPos);
00804 }
00805 doneSomething=1;
00806 }
00807 }
00808
00809
00810 if (GWEN_Io_LayerSocket_CheckForIncoming(io)!=GWEN_Io_Layer_WorkResultBlocking)
00811 doneSomething=1;
00812
00813
00814 return (doneSomething==0)?GWEN_Io_Layer_WorkResultBlocking:GWEN_Io_Layer_WorkResultOk;
00815 }
00816
00817
00818
00819 int GWEN_Io_LayerSocket_AddRequest(GWEN_IO_LAYER *io, GWEN_IO_REQUEST *r) {
00820 GWEN_IO_LAYER_SOCKET *xio;
00821 GWEN_IO_LAYER_STATUS st;
00822 uint32_t lflags;
00823
00824 assert(io);
00825 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_SOCKET, io);
00826 assert(xio);
00827
00828 st=GWEN_Io_Layer_GetStatus(io);
00829 lflags=GWEN_Io_Layer_GetFlags(io);
00830
00831 switch(GWEN_Io_Request_GetType(r)) {
00832 case GWEN_Io_Request_TypeConnect:
00833
00834 if (st==GWEN_Io_Layer_StatusConnected &&
00835 (lflags & GWEN_IO_LAYER_FLAGS_PASSIVE)) {
00836 DBG_INFO(GWEN_LOGDOMAIN, "Socket already connected");
00837 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, 0);
00838 return 0;
00839 }
00840 if (st!=GWEN_Io_Layer_StatusUnconnected &&
00841 st!=GWEN_Io_Layer_StatusDisconnected) {
00842 DBG_INFO(GWEN_LOGDOMAIN, "Socket is open");
00843 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_INVALID);
00844 return GWEN_ERROR_NOT_OPEN;
00845 }
00846
00847
00848 if (xio->connectRequest) {
00849 DBG_INFO(GWEN_LOGDOMAIN, "There already is a connect request");
00850 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_IN_PROGRESS);
00851 return GWEN_ERROR_IN_PROGRESS;
00852 }
00853 else {
00854 char addrBuffer[128];
00855 int port;
00856 int rv;
00857
00858
00859 GWEN_InetAddr_GetAddress(xio->peerAddr, addrBuffer, sizeof(addrBuffer));
00860 port=GWEN_InetAddr_GetPort(xio->peerAddr);
00861 DBG_INFO(GWEN_LOGDOMAIN, "Starting to connect to %s (port %d)", addrBuffer, port);
00862
00863
00864 GWEN_Io_Layer_SubFlags(io, GWEN_IO_LAYER_FLAGS_PASSIVE);
00865
00866
00867 rv=GWEN_Socket_Open(xio->socket);
00868 if (rv) {
00869 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00870 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, rv);
00871 return rv;
00872 }
00873
00874
00875 rv=GWEN_Socket_SetBlocking(xio->socket, 0);
00876 if (rv) {
00877 GWEN_Socket_Close(xio->socket);
00878 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00879 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, rv);
00880 return rv;
00881 }
00882
00883
00884 rv=GWEN_Proxy_Connect(xio->socket, xio->peerAddr, GWEN_Io_Request_GetGuiId(r));
00885
00886 if (rv) {
00887 if (rv!=GWEN_ERROR_IN_PROGRESS) {
00888
00889 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00890 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, rv);
00891 }
00892 else {
00893
00894 xio->connectRequest=r;
00895 GWEN_Io_Request_Attach(xio->connectRequest);
00896 GWEN_Io_Layer_SetStatus(io, GWEN_Io_Layer_StatusConnecting);
00897 }
00898 }
00899 else {
00900
00901 DBG_INFO(GWEN_LOGDOMAIN, "Immediately connected to %s (port %d)", addrBuffer, port);
00902 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, 0);
00903 GWEN_Io_Layer_SetStatus(io, GWEN_Io_Layer_StatusConnected);
00904 }
00905 }
00906 break;
00907
00908 case GWEN_Io_Request_TypeDisconnect:
00909
00910 if (st!=GWEN_Io_Layer_StatusConnected) {
00911 DBG_INFO(GWEN_LOGDOMAIN, "Io layer not connected");
00912 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_NOT_OPEN);
00913 return GWEN_ERROR_NOT_OPEN;
00914 }
00915 else {
00916 if ((xio->readRequest==NULL && xio->writeRequest==NULL) ||
00917 (GWEN_Io_Request_GetFlags(r) & GWEN_IO_REQUEST_FLAGS_FORCE)) {
00918
00919 if (!(lflags & GWEN_IO_LAYER_FLAGS_DONTCLOSE))
00920 GWEN_Socket_Close(xio->socket);
00921 GWEN_Io_LayerSocket_AbortRequests(io, GWEN_ERROR_ABORTED);
00922
00923
00924 GWEN_Io_Layer_SetStatus(io, GWEN_Io_Layer_StatusDisconnected);
00925 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, 0);
00926 }
00927 else {
00928
00929 return GWEN_ERROR_TRY_AGAIN;
00930 }
00931 }
00932 break;
00933
00934 case GWEN_Io_Request_TypeRead:
00935
00936 if (st!=GWEN_Io_Layer_StatusConnected) {
00937 DBG_INFO(GWEN_LOGDOMAIN, "Socket is not open");
00938 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_NOT_OPEN);
00939 return GWEN_ERROR_NOT_OPEN;
00940 }
00941
00942
00943 if (xio->readRequest) {
00944 DBG_INFO(GWEN_LOGDOMAIN, "There already is a read request");
00945 return GWEN_ERROR_TRY_AGAIN;
00946 }
00947
00948
00949 xio->readRequest=r;
00950 GWEN_Io_Request_Attach(xio->readRequest);
00951 break;
00952
00953 case GWEN_Io_Request_TypeWrite:
00954
00955 if (st!=GWEN_Io_Layer_StatusConnected) {
00956 DBG_INFO(GWEN_LOGDOMAIN, "File is not open");
00957 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_NOT_OPEN);
00958 return GWEN_ERROR_NOT_OPEN;
00959 }
00960
00961
00962 if (xio->writeRequest) {
00963 DBG_INFO(GWEN_LOGDOMAIN, "There already is a write request");
00964 return GWEN_ERROR_TRY_AGAIN;
00965 }
00966
00967
00968 xio->writeRequest=r;
00969 GWEN_Io_Request_Attach(xio->writeRequest);
00970 break;
00971
00972 default:
00973 DBG_INFO(GWEN_LOGDOMAIN, "This request type is not supported (%d)", GWEN_Io_Request_GetType(r));
00974 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_NOT_SUPPORTED);
00975 return GWEN_ERROR_NOT_SUPPORTED;
00976 }
00977
00978 return 0;
00979 }
00980
00981
00982
00983 int GWEN_Io_LayerSocket_DelRequest(GWEN_IO_LAYER *io, GWEN_IO_REQUEST *r) {
00984 GWEN_IO_LAYER_SOCKET *xio;
00985
00986 assert(io);
00987 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_SOCKET, io);
00988 assert(xio);
00989
00990 switch(GWEN_Io_Request_GetType(r)) {
00991 case GWEN_Io_Request_TypeRead:
00992 if (xio->readRequest==r) {
00993 DBG_DEBUG(GWEN_LOGDOMAIN, "Aborted read request");
00994 xio->readRequest=NULL;
00995 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_ABORTED);
00996 GWEN_Io_Request_free(r);
00997 }
00998 else {
00999
01000 DBG_INFO(GWEN_LOGDOMAIN, "Read request not registered with this io layer");
01001 return GWEN_ERROR_INVALID;
01002 }
01003 break;
01004
01005 case GWEN_Io_Request_TypeWrite:
01006 if (xio->writeRequest==r) {
01007 DBG_DEBUG(GWEN_LOGDOMAIN, "Aborted write request");
01008 xio->writeRequest=NULL;
01009 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_ABORTED);
01010 GWEN_Io_Request_free(r);
01011 }
01012 else {
01013
01014 DBG_INFO(GWEN_LOGDOMAIN, "Write request not registered with this io layer");
01015 return GWEN_ERROR_INVALID;
01016 }
01017 break;
01018
01019 case GWEN_Io_Request_TypeConnect:
01020 if (xio->connectRequest==r) {
01021 DBG_DEBUG(GWEN_LOGDOMAIN, "Aborted connect request");
01022 if (!(GWEN_Io_Layer_GetFlags(io) & GWEN_IO_LAYER_FLAGS_DONTCLOSE))
01023 GWEN_Socket_Close(xio->socket);
01024 GWEN_Io_Layer_SetStatus(io, GWEN_Io_Layer_StatusDisconnected);
01025 GWEN_Io_LayerSocket_AbortRequests(io, GWEN_ERROR_ABORTED);
01026 }
01027 else {
01028
01029 DBG_INFO(GWEN_LOGDOMAIN, "Read request not registered with this io layer");
01030 return GWEN_ERROR_INVALID;
01031 }
01032 break;
01033
01034 default:
01035 break;
01036 }
01037
01038 return 0;
01039 }
01040
01041
01042
01043 int GWEN_Io_LayerSocket_HasWaitingRequests(GWEN_IO_LAYER *io) {
01044 GWEN_IO_LAYER_SOCKET *xio;
01045
01046 assert(io);
01047 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_SOCKET, io);
01048 assert(xio);
01049
01050 if (xio->readRequest || xio->writeRequest || xio->connectRequest)
01051 return 1;
01052 else
01053 return 0;
01054 }
01055
01056
01057
01058 int GWEN_Io_LayerSocket_AddWaitingSockets(GWEN_IO_LAYER *io,
01059 GWEN_SOCKET_LIST2 *readSockets,
01060 GWEN_SOCKET_LIST2 *writeSockets) {
01061 GWEN_IO_LAYER_SOCKET *xio;
01062
01063 assert(io);
01064 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_SOCKET, io);
01065 assert(xio);
01066
01067 if (xio->readRequest || GWEN_Io_Layer_GetStatus(io)==GWEN_Io_Layer_StatusListening)
01068 GWEN_Socket_List2_PushBack(readSockets, xio->socket);
01069 if (xio->writeRequest || xio->connectRequest)
01070 GWEN_Socket_List2_PushBack(writeSockets, xio->socket);
01071
01072 return 0;
01073 }
01074
01075
01076
01077 int GWEN_Io_LayerSocket_Listen(GWEN_IO_LAYER *io) {
01078 GWEN_IO_LAYER_SOCKET *xio;
01079 char addrBuffer[128];
01080 int port;
01081 int rv;
01082
01083 assert(io);
01084 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_SOCKET, io);
01085 assert(xio);
01086
01087
01088 GWEN_InetAddr_GetAddress(xio->localAddr, addrBuffer, sizeof(addrBuffer));
01089 port=GWEN_InetAddr_GetPort(xio->localAddr);
01090
01091
01092 rv=GWEN_Socket_Open(xio->socket);
01093 if (rv) {
01094 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01095 return rv;
01096 }
01097
01098
01099 rv=GWEN_Socket_SetBlocking(xio->socket, 0);
01100 if (rv) {
01101 GWEN_Socket_Close(xio->socket);
01102 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01103 return rv;
01104 }
01105
01106
01107 rv=GWEN_Socket_SetReuseAddress(xio->socket, 1);
01108 if (rv) {
01109 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01110 }
01111
01112
01113 rv=GWEN_Socket_Bind(xio->socket, xio->localAddr);
01114 if (rv) {
01115 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01116 return rv;
01117 }
01118
01119
01120 DBG_NOTICE(GWEN_LOGDOMAIN, "Starting to listen on %s (port %d)", addrBuffer, port);
01121 rv=GWEN_Socket_Listen(xio->socket, 10);
01122 if (rv) {
01123 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01124 return rv;
01125 }
01126
01127 GWEN_Io_Layer_SetStatus(io, GWEN_Io_Layer_StatusListening);
01128
01129 return 0;
01130 }
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143