summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/IO/IO.c37
-rw-r--r--src/IO/dpi.c17
-rw-r--r--src/IO/http.c16
-rw-r--r--src/IO/iowatch.cc6
-rw-r--r--src/capi.c29
-rw-r--r--src/web.cc1
6 files changed, 71 insertions, 35 deletions
diff --git a/src/IO/IO.c b/src/IO/IO.c
index ddcbe2e7..40677345 100644
--- a/src/IO/IO.c
+++ b/src/IO/IO.c
@@ -59,13 +59,13 @@ void a_IO_ccc(int Op, int Branch, int Dir, ChainLink *Info,
/* IO API - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
- * Return a newly created, and initialized, 'io' struct
+ * Return a new, initialized, 'io' struct
*/
-static IOData_t *IO_new(int op, int fd)
+static IOData_t *IO_new(int op)
{
IOData_t *io = dNew0(IOData_t, 1);
io->Op = op;
- io->FD = fd;
+ io->FD = -1;
io->Flags = 0;
io->Key = 0;
io->Buf = dStr_sized_new(IOBufLen);
@@ -309,6 +309,11 @@ static void IO_fd_write_cb(int fd, void *data)
*/
static void IO_submit(IOData_t *r_io)
{
+ if (r_io->FD < 0) {
+ MSG_ERR("IO_submit: FD not initialized\n");
+ return;
+ }
+
/* Insert this IO in ValidIOs */
IO_ins(r_io);
@@ -346,14 +351,18 @@ void a_IO_ccc(int Op, int Branch, int Dir, ChainLink *Info,
/* Write data using select */
switch (Op) {
case OpStart:
- io = IO_new(IOWrite, *(int*)Data1); /* SockFD */
+ io = IO_new(IOWrite);
Info->LocalKey = io;
break;
case OpSend:
io = Info->LocalKey;
- dbuf = Data1;
- dStr_append_l(io->Buf, dbuf->Buf, dbuf->Size);
- IO_submit(io);
+ if (Data2 && !strcmp(Data2, "FD")) {
+ io->FD = *(int*)Data1; /* SockFD */
+ } else {
+ dbuf = Data1;
+ dStr_append_l(io->Buf, dbuf->Buf, dbuf->Size);
+ IO_submit(io);
+ }
break;
case OpEnd:
case OpAbort:
@@ -371,7 +380,7 @@ void a_IO_ccc(int Op, int Branch, int Dir, ChainLink *Info,
MSG_WARN("Unused CCC\n");
break;
}
- } else { /* FWD */
+ } else { /* 1 FWD */
/* Write-data status */
switch (Op) {
default:
@@ -385,10 +394,16 @@ void a_IO_ccc(int Op, int Branch, int Dir, ChainLink *Info,
/* This part catches the reader's messages */
switch (Op) {
case OpStart:
- io = IO_new(IORead, *(int*)Data2); /* SockFD */
+ io = IO_new(IORead);
Info->LocalKey = io;
io->Info = Info;
- IO_submit(io);
+ break;
+ case OpSend:
+ io = Info->LocalKey;
+ if (Data2 && !strcmp(Data2, "FD")) {
+ io->FD = *(int*)Data1; /* SockFD */
+ IO_submit(io);
+ }
break;
case OpAbort:
io = Info->LocalKey;
@@ -400,7 +415,7 @@ void a_IO_ccc(int Op, int Branch, int Dir, ChainLink *Info,
MSG_WARN("Unused CCC\n");
break;
}
- } else { /* FWD */
+ } else { /* 2 FWD */
/* Send read-data */
io = Data1;
switch (Op) {
diff --git a/src/IO/dpi.c b/src/IO/dpi.c
index 34932a6a..7d5b550c 100644
--- a/src/IO/dpi.c
+++ b/src/IO/dpi.c
@@ -615,13 +615,13 @@ void a_Dpi_ccc(int Op, int Branch, int Dir, ChainLink *Info,
*fd = SockFD;
Info->LocalKey = fd;
a_Chain_link_new(Info, a_Dpi_ccc, BCK, a_IO_ccc, 1, 1);
- a_Chain_bcb(OpStart, Info, Info->LocalKey, NULL);
- /* tell the capi to start the receiving branch */
- a_Chain_fcb(OpSend, Info, Info->LocalKey, "SockFD");
+ a_Chain_bcb(OpStart, Info, NULL, NULL);
}
}
if (st == 0 && SockFD != -1) {
+ a_Chain_bcb(OpSend, Info, &SockFD, "FD");
+ a_Chain_fcb(OpSend, Info, &SockFD, "FD");
a_Chain_fcb(OpSend, Info, NULL, "DpidOK");
} else {
MSG_ERR("dpi.c: can't start dpi daemon\n");
@@ -645,7 +645,7 @@ void a_Dpi_ccc(int Op, int Branch, int Dir, ChainLink *Info,
MSG_WARN("Unused CCC\n");
break;
}
- } else { /* FWD */
+ } else { /* 1 FWD */
/* Send commands to dpi-server (status) */
switch (Op) {
case OpAbort:
@@ -675,7 +675,7 @@ void a_Dpi_ccc(int Op, int Branch, int Dir, ChainLink *Info,
MSG_WARN("Unused CCC\n");
break;
}
- } else { /* BCK */
+ } else { /* 2 BCK */
switch (Op) {
case OpStart:
conn = Dpi_conn_new(Info);
@@ -687,7 +687,12 @@ void a_Dpi_ccc(int Op, int Branch, int Dir, ChainLink *Info,
}
a_Chain_link_new(Info, a_Dpi_ccc, BCK, a_IO_ccc, 2, 2);
- a_Chain_bcb(OpStart, Info, NULL, Data1); /* IORead, SockFD */
+ a_Chain_bcb(OpStart, Info, NULL, NULL); /* IORead */
+ break;
+ case OpSend:
+ if (Data2 && !strcmp(Data2, "FD")) {
+ a_Chain_bcb(OpSend, Info, Data1, Data2);
+ }
break;
case OpAbort:
a_Chain_bcb(OpAbort, Info, NULL, NULL);
diff --git a/src/IO/http.c b/src/IO/http.c
index 84120a92..09ae34d3 100644
--- a/src/IO/http.c
+++ b/src/IO/http.c
@@ -299,14 +299,9 @@ static void Http_send_query(ChainLink *Info, SocketData_t *S)
_MSG_BW(S->web, 1, "Sending query to %s...", URL_HOST_(S->web->url));
/* send query */
- a_Chain_link_new(Info, a_Http_ccc, BCK, a_IO_ccc, 1, 1);
- a_Chain_bcb(OpStart, Info, &S->SockFD, NULL);
a_Chain_bcb(OpSend, Info, dbuf, NULL);
dFree(dbuf);
dStr_free(query, 1);
-
- /* Tell the cache to start the receiving CCC for the answer */
- a_Chain_fcb(OpSend, Info, &S->SockFD, "SockFD");
}
/*
@@ -379,6 +374,8 @@ static int Http_connect_socket(ChainLink *Info)
Http_socket_close(S);
MSG("Http_connect_socket ERROR: %s\n", dStrerror(S->Err));
} else {
+ a_Chain_bcb(OpSend, Info, &S->SockFD, "FD");
+ a_Chain_fcb(OpSend, Info, &S->SockFD, "FD");
Http_send_query(S->Info, S);
return 0; /* Success */
}
@@ -476,6 +473,7 @@ void a_Http_dns_cb(int Status, Dlist *addr_list, void *data)
S = a_Klist_get_data(ValidSocks, SKey);
if (S) {
if (!a_Web_valid(S->web)) {
+ a_Chain_bcb(OpAbort, S->Info, NULL, NULL);
a_Chain_fcb(OpAbort, S->Info, NULL, NULL);
dFree(S->Info);
Http_socket_free(SKey);
@@ -486,6 +484,7 @@ void a_Http_dns_cb(int Status, Dlist *addr_list, void *data)
/* start connecting the socket */
if (Http_connect_socket(S->Info) < 0) {
MSG_BW(S->web, 1, "ERROR: %s", dStrerror(S->Err));
+ a_Chain_bcb(OpAbort, S->Info, NULL, NULL);
a_Chain_fcb(OpAbort, S->Info, NULL, NULL);
dFree(S->Info);
Http_socket_free(SKey);
@@ -495,6 +494,7 @@ void a_Http_dns_cb(int Status, Dlist *addr_list, void *data)
/* DNS wasn't able to resolve the hostname */
MSG_BW(S->web, 0, "ERROR: Dns can't resolve %s",
(S->use_proxy) ? URL_HOST_(HTTP_Proxy) : URL_HOST_(S->web->url));
+ a_Chain_bcb(OpAbort, S->Info, NULL, NULL);
a_Chain_fcb(OpAbort, S->Info, NULL, NULL);
dFree(S->Info);
Http_socket_free(SKey);
@@ -560,6 +560,10 @@ void a_Http_ccc(int Op, int Branch, int Dir, ChainLink *Info,
/* ( Data1 = Web ) */
SKey = Http_sock_new();
Info->LocalKey = INT2VOIDP(SKey);
+ /* link IO */
+ a_Chain_link_new(Info, a_Http_ccc, BCK, a_IO_ccc, 1, 1);
+ a_Chain_bcb(OpStart, Info, NULL, NULL);
+ /* async. connection */
Http_get(Info, Data1);
break;
case OpEnd:
@@ -575,7 +579,7 @@ void a_Http_ccc(int Op, int Branch, int Dir, ChainLink *Info,
dFree(Info);
break;
}
- } else { /* FWD */
+ } else { /* 1 FWD */
/* HTTP send-query status branch */
switch (Op) {
default:
diff --git a/src/IO/iowatch.cc b/src/IO/iowatch.cc
index 0749e24c..f67b711f 100644
--- a/src/IO/iowatch.cc
+++ b/src/IO/iowatch.cc
@@ -22,7 +22,8 @@ using namespace fltk;
//
void a_IOwatch_add_fd(int fd, int when, FileHandler Callback, void *usr_data=0)
{
- add_fd(fd, when, Callback, usr_data);
+ if (fd >= 0)
+ add_fd(fd, when, Callback, usr_data);
}
//
@@ -30,6 +31,7 @@ void a_IOwatch_add_fd(int fd, int when, FileHandler Callback, void *usr_data=0)
//
void a_IOwatch_remove_fd(int fd, int when)
{
- remove_fd(fd, when);
+ if (fd >= 0)
+ remove_fd(fd, when);
}
diff --git a/src/capi.c b/src/capi.c
index e857127f..49e0ab80 100644
--- a/src/capi.c
+++ b/src/capi.c
@@ -367,6 +367,9 @@ int a_Capi_open_url(DilloWeb *web, CA_Callback_t Call, void *CbData)
a_Capi_conn_abort_by_url(web->url);
/* create a new connection and start the CCC operations */
conn = Capi_conn_new(web->url, web->bw, "http", "none");
+ /* start the reception branch before the query one because the DNS
+ * may callback immediatly. This may avoid a race condition. */
+ a_Capi_ccc(OpStart, 2, BCK, a_Chain_new(), conn, "http");
a_Capi_ccc(OpStart, 1, BCK, a_Chain_new(), conn, web);
}
use_cache = 1;
@@ -475,6 +478,7 @@ int a_Capi_dpi_send_cmd(DilloUrl *url, void *bw, char *cmd, char *server,
/* Create a new connection data struct and add it to the list */
conn = Capi_conn_new(url, bw, server, cmd);
/* start the CCC operations */
+ a_Capi_ccc(OpStart, 2, BCK, a_Chain_new(), conn, server);
a_Capi_ccc(OpStart, 1, BCK, a_Chain_new(), conn, server);
} else {
@@ -557,18 +561,17 @@ void a_Capi_ccc(int Op, int Branch, int Dir, ChainLink *Info,
MSG_WARN("Unused CCC\n");
break;
}
- } else { /* FWD */
+ } else { /* 1 FWD */
/* Command sending branch (status) */
switch (Op) {
case OpSend:
if (!Data2) {
MSG_WARN("Capi.c: Opsend [1F] Data2 = NULL\n");
- } else if (strcmp(Data2, "SockFD") == 0) {
- /* start the receiving branch */
- capi_conn_t *conn = Info->LocalKey;
+ } else if (strcmp(Data2, "FD") == 0) {
+ conn = Info->LocalKey;
conn->SockFD = *(int*)Data1;
- a_Capi_ccc(OpStart, 2, BCK, a_Chain_new(), Info->LocalKey,
- conn->server);
+ /* communicate the FD through the answer branch */
+ a_Capi_ccc(OpSend, 2, BCK, conn->InfoRecv, &conn->SockFD, "FD");
} else if (strcmp(Data2, "DpidOK") == 0) {
/* resume pending dpi requests */
Capi_conn_resume();
@@ -596,16 +599,22 @@ void a_Capi_ccc(int Op, int Branch, int Dir, ChainLink *Info,
} else if (Branch == 2) {
if (Dir == BCK) {
- /* Server listening branch (status)
- * (Data1 = conn; Data2 = {"HttpFD" | "DpiFD"}) */
+ /* Answer branch */
switch (Op) {
case OpStart:
+ /* Data1 = conn; Data2 = {"http" | "<dpi server name>"} */
conn = Data1;
Capi_conn_ref(conn);
Info->LocalKey = conn;
conn->InfoRecv = Info;
a_Chain_link_new(Info, a_Capi_ccc, BCK, a_Dpi_ccc, 2, 2);
- a_Chain_bcb(OpStart, Info, &conn->SockFD, Data2);
+ a_Chain_bcb(OpStart, Info, NULL, Data2);
+ break;
+ case OpSend:
+ /* Data1 = FD */
+ if (Data2 && strcmp(Data2, "FD") == 0) {
+ a_Chain_bcb(OpSend, Info, Data1, Data2);
+ }
break;
case OpAbort:
conn = Info->LocalKey;
@@ -618,7 +627,7 @@ void a_Capi_ccc(int Op, int Branch, int Dir, ChainLink *Info,
MSG_WARN("Unused CCC\n");
break;
}
- } else { /* FWD */
+ } else { /* 2 FWD */
/* Server listening branch */
switch (Op) {
case OpSend:
diff --git a/src/web.cc b/src/web.cc
index d3408be9..79107b40 100644
--- a/src/web.cc
+++ b/src/web.cc
@@ -139,6 +139,7 @@ void a_Web_free(DilloWeb *web)
a_Image_unref(web->Image);
dFree(web->filename);
dList_remove(ValidWebs, (void *)web);
+ _MSG("a_Web_free: ValidWebs=%d\n", dList_length(ValidWebs));
dFree(web);
}