# include <Evil.h>
#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_WINSOCK2_H
+# include <winsock2.h>
+#endif
+
#include "Ecore.h"
#include "ecore_private.h"
#include "Ecore_Con.h"
Ecore_Con_Event_Server_Data *e;
e = ecore_con_event_server_data_alloc();
- EINA_SAFETY_ON_NULL_RETURN(e);
+ if (!e)
+ {
+ if (!duplicate) free(buf);
+ return;
+ }
svr->event_count = eina_list_append(svr->event_count, e);
_ecore_con_server_timer_update(svr);
static void
_ecore_con_cl_read(Ecore_Con_Server *svr)
{
- int num = 0;
- Eina_Bool lost_server = EINA_TRUE;
+ int num2 = 0, num = 0;
+#ifdef FIONREAD
+ double lr;
+ unsigned char *buf = NULL;
+#else
unsigned char buf[READBUFSIZ];
+#endif
+ Eina_Bool lost_server = EINA_TRUE;
DBG("svr=%p", svr);
lost_server = EINA_FALSE;
_ecore_con_server_timer_update(svr);
}
-
+#ifdef FIONREAD
+# ifdef _WIN32
+ if (ioctlsocket(svr->fd, FIONREAD, &num)) goto error;
+# else
+ errno = 0;
+ if (ioctl(svr->fd, FIONREAD, &num)) goto error;
+# endif
+ if (!num) return; /* FIXME: this shouldn't happen */
+ lr = ecore_time_get();
+ if ((num < 100) && (lr - svr->last_read < 0.01)) num2 = READBUFSIZ / 8;
+ else if (num > READBUFSIZ) num2 = READBUFSIZ;
+ if (num2)
+ {
+ DBG("%d bytes available for read from ioctl(), trying size (%d) to avoid congestion", num, num2);
+ num = num2;
+ }
+ else
+ DBG("%d bytes available for read", num);
+ svr->last_read = lr;
+ buf = malloc(num);
+ if (!buf) goto error;
+#else
+ num = sizeof(buf);
+ (void)num2;
+#endif
if (svr->ecs_state || !(svr->type & ECORE_CON_SSL))
{
- errno = 0;
- num = read(svr->fd, buf, sizeof(buf));
+ num = read(svr->fd, buf, num);
/* 0 is not a valid return value for a tcp socket */
- if ((num > 0) || ((num < 0) && (errno == EAGAIN)))
- lost_server = EINA_FALSE;
- else if (num < 0)
- ecore_con_event_server_error(svr, strerror(errno));
+ if ((num < 0) || (errno && (errno != EAGAIN))) goto error;
}
else
{
- num = ecore_con_ssl_server_read(svr, buf, sizeof(buf));
+ num = ecore_con_ssl_server_read(svr, buf, num);
/* this is not an actual 0 return, 0 here just means non-fatal error such as EAGAIN */
- if (num >= 0)
- lost_server = EINA_FALSE;
+ if (num < 0) goto error;
}
if ((!svr->delete_me) && (num > 0))
if (svr->ecs_state)
ecore_con_socks_read(svr, buf, num);
else
- ecore_con_event_server_data(svr, buf, num, EINA_TRUE);
+ ecore_con_event_server_data(svr, buf, num,
+#ifdef FIONREAD
+ EINA_FALSE
+#else
+ EINA_TRUE
+#endif
+ );
}
- if (lost_server)
- _ecore_con_server_kill(svr);
+ return;
+error:
+#ifndef _WIN32
+ /* FIXME: strerror on windows */
+ ecore_con_event_server_error(svr, strerror(errno));
+#endif
+#ifdef FIONREAD
+ free(buf);
+#endif
+ _ecore_con_server_kill(svr);
}
static Eina_Bool
DBG("SOCKS: %d bytes", num);
if (num < 8)
{
+#ifdef FIONREAD
+ if (!svr->ecs_recvbuf)
+ svr->ecs_recvbuf = eina_binbuf_manage_new_length(buf, num);
+ else
+ eina_binbuf_append_length(svr->ecs_recvbuf, buf, num);
+ if (!svr->ecs_recvbuf) goto error;
+#else
if (!svr->ecs_recvbuf) svr->ecs_recvbuf = eina_binbuf_new();
if (!svr->ecs_recvbuf) goto error;
eina_binbuf_append_length(svr->ecs_recvbuf, buf, num);
+#endif
/* the slowest connection on earth */
- if (eina_binbuf_length_get(svr->ecs_recvbuf) != 8) return;
+ if (eina_binbuf_length_get(svr->ecs_recvbuf) != 8)
+ {
+#ifdef FIONREAD
+ free(buf);
+#endif
+ return;
+ }
data = eina_binbuf_string_get(svr->ecs_recvbuf);
}
else if (num > 8) goto error;
svr->ecs_state = ECORE_CON_SOCKS_STATE_DONE;
INF("PROXY CONNECTED");
if (svr->ecs_recvbuf) eina_binbuf_free(svr->ecs_recvbuf);
+#ifdef FIONREAD
+ else free(buf);
+#endif
svr->ecs_recvbuf = NULL;
svr->ecs_buf_offset = svr->ecs_addrlen = 0;
memset(svr->ecs_addr, 0, sizeof(svr->ecs_addr));
}
return;
error:
+#ifdef FIONREAD
+ free(buf);
+#endif
_ecore_con_server_kill(svr);
}