added MIO_DEV_SCK_LENIENT to set on the state field of a socket device
added MIO_DEV_SCK_BIND_LENIENT to use to set MIO_DEV_SCK_LENIENT on a listening socket. fixed some minor bugs here and there
This commit is contained in:
parent
b9a47faff6
commit
0baa0820ae
@ -76,18 +76,31 @@ printf ("CRITICAL ERROR ---> too many heap chunks...\n");
|
|||||||
}
|
}
|
||||||
|
|
||||||
x = malloc (size);
|
x = malloc (size);
|
||||||
if (x) ((mmgr_stat_t*)mmgr->ctx)->total_count++;
|
if (x)
|
||||||
|
{
|
||||||
|
((mmgr_stat_t*)mmgr->ctx)->total_count++;
|
||||||
|
/*printf ("MMGR total_count INCed to %d => %p\n", ((mmgr_stat_t*)mmgr->ctx)->total_count, x);*/
|
||||||
|
}
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* mmgr_realloc (mio_mmgr_t* mmgr, void* ptr, mio_oow_t size)
|
static void* mmgr_realloc (mio_mmgr_t* mmgr, void* ptr, mio_oow_t size)
|
||||||
{
|
{
|
||||||
return realloc (ptr, size);
|
void* x;
|
||||||
|
|
||||||
|
x = realloc (ptr, size);
|
||||||
|
if (x && !ptr)
|
||||||
|
{
|
||||||
|
((mmgr_stat_t*)mmgr->ctx)->total_count++;
|
||||||
|
/*printf ("MMGR total_count INCed to %d => %p\n", ((mmgr_stat_t*)mmgr->ctx)->total_count, x);*/
|
||||||
|
}
|
||||||
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mmgr_free (mio_mmgr_t* mmgr, void* ptr)
|
static void mmgr_free (mio_mmgr_t* mmgr, void* ptr)
|
||||||
{
|
{
|
||||||
((mmgr_stat_t*)mmgr->ctx)->total_count--;
|
((mmgr_stat_t*)mmgr->ctx)->total_count--;
|
||||||
|
/*printf ("MMGR total_count DECed to %d => %p\n", ((mmgr_stat_t*)mmgr->ctx)->total_count, ptr);*/
|
||||||
return free (ptr);
|
return free (ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -889,8 +902,8 @@ int main (int argc, char* argv[])
|
|||||||
tcp_bind.options |= MIO_DEV_SCK_BIND_SSL;
|
tcp_bind.options |= MIO_DEV_SCK_BIND_SSL;
|
||||||
tcp_bind.ssl_certfile = "localhost.crt";
|
tcp_bind.ssl_certfile = "localhost.crt";
|
||||||
tcp_bind.ssl_keyfile = "localhost.key";
|
tcp_bind.ssl_keyfile = "localhost.key";
|
||||||
|
MIO_INIT_NTIME (&tcp_bind.ssl_accept_tmout, 5, 1);
|
||||||
#endif
|
#endif
|
||||||
MIO_INIT_NTIME (&tcp_bind.accept_tmout, 5, 1);
|
|
||||||
|
|
||||||
if (mio_dev_sck_bind(tcp[2], &tcp_bind) <= -1)
|
if (mio_dev_sck_bind(tcp[2], &tcp_bind) <= -1)
|
||||||
{
|
{
|
||||||
|
@ -344,6 +344,8 @@ static void client_on_disconnect (mio_dev_sck_t* sck)
|
|||||||
sck_xtn_t* sckxtn = mio_dev_sck_getxtn(sck);
|
sck_xtn_t* sckxtn = mio_dev_sck_getxtn(sck);
|
||||||
printf ("** HTTS - client disconnect %p\n", sck);
|
printf ("** HTTS - client disconnect %p\n", sck);
|
||||||
fini_client (sck->mio, &sckxtn->c);
|
fini_client (sck->mio, &sckxtn->c);
|
||||||
|
|
||||||
|
/* TODO: remove it from the list of clients */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
@ -410,15 +412,15 @@ static void listener_on_disconnect (mio_dev_sck_t* sck)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case MIO_DEV_SCK_ACCEPTING_SSL:
|
case MIO_DEV_SCK_ACCEPTING_SSL:
|
||||||
MIO_INFO1 (sck->mio, "INCOMING SSL-ACCEPT GOT DISCONNECTED(%d) ....\n", (int)sck->sck);
|
MIO_INFO1 (sck->mio, "LISTENER INCOMING SSL-ACCEPT GOT DISCONNECTED(%d) ....\n", (int)sck->sck);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MIO_DEV_SCK_ACCEPTED:
|
case MIO_DEV_SCK_ACCEPTED:
|
||||||
MIO_INFO1 (sck->mio, "INCOMING CLIENT BEING SERVED GOT DISCONNECTED(%d).......\n", (int)sck->sck);
|
MIO_INFO1 (sck->mio, "LISTENER INCOMING CLIENT BEING SERVED GOT DISCONNECTED(%d).......\n", (int)sck->sck);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
MIO_INFO1 (sck->mio, "DISCONNECTED AFTER ALL(%d).......\n", (int)sck->sck);
|
MIO_INFO1 (sck->mio, "LISTENER DISCONNECTED AFTER ALL(%d).......\n", (int)sck->sck);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -427,6 +429,8 @@ static void listener_on_disconnect (mio_dev_sck_t* sck)
|
|||||||
* for a listener socket, these fields must be NULL */
|
* for a listener socket, these fields must be NULL */
|
||||||
MIO_ASSERT (sck->mio, sckxtn->c.htrd == MIO_NULL);
|
MIO_ASSERT (sck->mio, sckxtn->c.htrd == MIO_NULL);
|
||||||
MIO_ASSERT (sck->mio, sckxtn->c.sbuf == MIO_NULL);
|
MIO_ASSERT (sck->mio, sckxtn->c.sbuf == MIO_NULL);
|
||||||
|
|
||||||
|
sckxtn->htts->lsck = MIO_NULL; /* let the htts service forget about this listening socket */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -478,8 +482,8 @@ mio_svc_htts_t* mio_svc_htts_start (mio_t* mio, const mio_skad_t* bind_addr)
|
|||||||
|
|
||||||
MIO_MEMSET (&info, 0, MIO_SIZEOF(info));
|
MIO_MEMSET (&info, 0, MIO_SIZEOF(info));
|
||||||
info.b.localaddr = *bind_addr;
|
info.b.localaddr = *bind_addr;
|
||||||
info.b.options = MIO_DEV_SCK_BIND_REUSEADDR | MIO_DEV_SCK_BIND_REUSEPORT;
|
info.b.options = MIO_DEV_SCK_BIND_REUSEADDR | MIO_DEV_SCK_BIND_REUSEPORT | MIO_DEV_SCK_BIND_LENIENT;
|
||||||
MIO_INIT_NTIME (&info.b.accept_tmout, 5, 1);
|
/*MIO_INIT_NTIME (&info.b.ssl_accept_tmout, 5, 1);*/
|
||||||
if (mio_dev_sck_bind(htts->lsck, &info.b) <= -1) goto oops;
|
if (mio_dev_sck_bind(htts->lsck, &info.b) <= -1) goto oops;
|
||||||
|
|
||||||
info.l.backlogs = 255;
|
info.l.backlogs = 255;
|
||||||
|
@ -221,6 +221,8 @@ typedef enum mio_dev_sck_ioctl_cmd_t mio_dev_sck_ioctl_cmd_t;
|
|||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define MIO_DEV_SCK_GET_PROGRESS(dev) ((dev)->state & MIO_DEV_SCK_ALL_PROGRESS_BITS)
|
#define MIO_DEV_SCK_GET_PROGRESS(dev) ((dev)->state & MIO_DEV_SCK_ALL_PROGRESS_BITS)
|
||||||
|
#define MIO_DEV_SCK_GET_TOLERANT(dev) ((dev)->state & MIO_DEV_SCK_
|
||||||
|
|
||||||
|
|
||||||
enum mio_dev_sck_state_t
|
enum mio_dev_sck_state_t
|
||||||
{
|
{
|
||||||
@ -233,9 +235,9 @@ enum mio_dev_sck_state_t
|
|||||||
MIO_DEV_SCK_ACCEPTED = (1 << 5),
|
MIO_DEV_SCK_ACCEPTED = (1 << 5),
|
||||||
|
|
||||||
/* the following items can be bitwise-ORed with an exclusive item above */
|
/* the following items can be bitwise-ORed with an exclusive item above */
|
||||||
|
MIO_DEV_SCK_LENIENT = (1 << 14),
|
||||||
MIO_DEV_SCK_INTERCEPTED = (1 << 15),
|
MIO_DEV_SCK_INTERCEPTED = (1 << 15),
|
||||||
|
|
||||||
|
|
||||||
/* convenience bit masks */
|
/* convenience bit masks */
|
||||||
MIO_DEV_SCK_ALL_PROGRESS_BITS = (MIO_DEV_SCK_CONNECTING |
|
MIO_DEV_SCK_ALL_PROGRESS_BITS = (MIO_DEV_SCK_CONNECTING |
|
||||||
MIO_DEV_SCK_CONNECTING_SSL |
|
MIO_DEV_SCK_CONNECTING_SSL |
|
||||||
@ -313,6 +315,7 @@ enum mio_dev_sck_bind_option_t
|
|||||||
/* TODO: more options --- SO_RCVBUF, SO_SNDBUF, SO_RCVTIMEO, SO_SNDTIMEO, SO_KEEPALIVE */
|
/* TODO: more options --- SO_RCVBUF, SO_SNDBUF, SO_RCVTIMEO, SO_SNDTIMEO, SO_KEEPALIVE */
|
||||||
/* BINDTODEVICE??? */
|
/* BINDTODEVICE??? */
|
||||||
|
|
||||||
|
MIO_DEV_SCK_BIND_LENIENT = (1 << 14), /* for now, accept failure doesn't affect the listing socket if this is set */
|
||||||
MIO_DEV_SCK_BIND_SSL = (1 << 15)
|
MIO_DEV_SCK_BIND_SSL = (1 << 15)
|
||||||
};
|
};
|
||||||
typedef enum mio_dev_sck_bind_option_t mio_dev_sck_bind_option_t;
|
typedef enum mio_dev_sck_bind_option_t mio_dev_sck_bind_option_t;
|
||||||
@ -320,13 +323,13 @@ typedef enum mio_dev_sck_bind_option_t mio_dev_sck_bind_option_t;
|
|||||||
typedef struct mio_dev_sck_bind_t mio_dev_sck_bind_t;
|
typedef struct mio_dev_sck_bind_t mio_dev_sck_bind_t;
|
||||||
struct mio_dev_sck_bind_t
|
struct mio_dev_sck_bind_t
|
||||||
{
|
{
|
||||||
int options;
|
int options; /** 0 or bitwise-OR'ed of mio_dev_sck_bind_option_t enumerators */
|
||||||
mio_skad_t localaddr;
|
mio_skad_t localaddr;
|
||||||
/* TODO: add device name for BIND_TO_DEVICE */
|
/* TODO: add device name for BIND_TO_DEVICE */
|
||||||
|
|
||||||
const mio_bch_t* ssl_certfile;
|
const mio_bch_t* ssl_certfile;
|
||||||
const mio_bch_t* ssl_keyfile;
|
const mio_bch_t* ssl_keyfile;
|
||||||
mio_ntime_t accept_tmout;
|
mio_ntime_t ssl_accept_tmout;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum mio_dev_sck_connect_option_t
|
enum mio_dev_sck_connect_option_t
|
||||||
@ -349,14 +352,6 @@ struct mio_dev_sck_listen_t
|
|||||||
int backlogs;
|
int backlogs;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct mio_dev_sck_accept_t mio_dev_sck_accept_t;
|
|
||||||
struct mio_dev_sck_accept_t
|
|
||||||
{
|
|
||||||
mio_syshnd_t sck;
|
|
||||||
/* TODO: add timeout */
|
|
||||||
mio_skad_t remoteaddr;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct mio_dev_sck_t
|
struct mio_dev_sck_t
|
||||||
{
|
{
|
||||||
MIO_DEV_HEADER;
|
MIO_DEV_HEADER;
|
||||||
|
@ -179,6 +179,7 @@ void mio_fini (mio_t* mio)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* kill services before killing devices */
|
||||||
while (!MIO_SVCL_IS_EMPTY(&mio->actsvc))
|
while (!MIO_SVCL_IS_EMPTY(&mio->actsvc))
|
||||||
{
|
{
|
||||||
mio_svc_t* svc;
|
mio_svc_t* svc;
|
||||||
@ -751,7 +752,6 @@ static int kill_and_free_device (mio_dev_t* dev, int force)
|
|||||||
MIO_ASSERT (mio, !(dev->dev_cap & MIO_DEV_CAP_ACTIVE));
|
MIO_ASSERT (mio, !(dev->dev_cap & MIO_DEV_CAP_ACTIVE));
|
||||||
MIO_ASSERT (mio, !(dev->dev_cap & MIO_DEV_CAP_HALTED));
|
MIO_ASSERT (mio, !(dev->dev_cap & MIO_DEV_CAP_HALTED));
|
||||||
|
|
||||||
|
|
||||||
if (dev->dev_mth->kill(dev, force) <= -1)
|
if (dev->dev_mth->kill(dev, force) <= -1)
|
||||||
{
|
{
|
||||||
if (force >= 2) goto free_device;
|
if (force >= 2) goto free_device;
|
||||||
@ -909,6 +909,8 @@ void mio_dev_halt (mio_dev_t* dev)
|
|||||||
|
|
||||||
if (dev->dev_cap & MIO_DEV_CAP_ACTIVE)
|
if (dev->dev_cap & MIO_DEV_CAP_ACTIVE)
|
||||||
{
|
{
|
||||||
|
MIO_DEBUG1 (mio, "HALTING DEVICE %p\n", dev);
|
||||||
|
|
||||||
/* delink the device object from the active device list */
|
/* delink the device object from the active device list */
|
||||||
MIO_DEVL_UNLINK_DEV (dev);
|
MIO_DEVL_UNLINK_DEV (dev);
|
||||||
dev->dev_cap &= ~MIO_DEV_CAP_ACTIVE;
|
dev->dev_cap &= ~MIO_DEV_CAP_ACTIVE;
|
||||||
@ -1160,6 +1162,11 @@ static int __dev_write (mio_dev_t* dev, const void* data, mio_iolen_t len, const
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* the write callback should return at most the number of requested
|
||||||
|
* bytes. but returning more is harmless as urem is of a signed type.
|
||||||
|
* for a zero-length request, it's necessary to return at least 1
|
||||||
|
* to indicate successful acknowlegement. otherwise, it gets enqueued
|
||||||
|
* as shown in the 'if' block right above. */
|
||||||
urem -= ulen;
|
urem -= ulen;
|
||||||
uptr += ulen;
|
uptr += ulen;
|
||||||
}
|
}
|
||||||
|
@ -360,7 +360,6 @@ struct mio_dev_t
|
|||||||
(dev)->dev_next->dev_prev = (dev)->dev_prev; \
|
(dev)->dev_next->dev_prev = (dev)->dev_prev; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
#define MIO_DEVL_INIT(lh) ((lh)->dev_next = (lh)->dev_prev = lh)
|
#define MIO_DEVL_INIT(lh) ((lh)->dev_next = (lh)->dev_prev = lh)
|
||||||
#define MIO_DEVL_FIRST_DEV(lh) ((lh)->dev_next)
|
#define MIO_DEVL_FIRST_DEV(lh) ((lh)->dev_next)
|
||||||
#define MIO_DEVL_LAST_DEV(lh) ((lh)->dev_prev)
|
#define MIO_DEVL_LAST_DEV(lh) ((lh)->dev_prev)
|
||||||
|
@ -517,14 +517,17 @@ static int dev_sck_write_stateful (mio_dev_t* dev, const void* data, mio_iolen_t
|
|||||||
|
|
||||||
if (*len <= 0)
|
if (*len <= 0)
|
||||||
{
|
{
|
||||||
/* it's a writing finish indicator. close the writing end of
|
/* the write handler for a stream device must handle a zero-length
|
||||||
* the socket, probably leaving it in the half-closed state */
|
* writing request specially. it's a writing finish indicator. close
|
||||||
|
* the writing end of the socket, probably leaving it in the half-closed state */
|
||||||
if (shutdown(rdev->sck, SHUT_WR) == -1)
|
if (shutdown(rdev->sck, SHUT_WR) == -1)
|
||||||
{
|
{
|
||||||
mio_seterrwithsyserr (mio, 0, errno);
|
mio_seterrwithsyserr (mio, 0, errno);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* it must return a non-zero positive value. if it returns 0, this request
|
||||||
|
* gets enqueued by the core. we must aovid it */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -658,7 +661,6 @@ static int dev_sck_write_stateless (mio_dev_t* dev, const void* data, mio_iolen_
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int dev_sck_writev_stateless (mio_dev_t* dev, const mio_iovec_t* iov, mio_iolen_t* iovcnt, const mio_devaddr_t* dstaddr)
|
static int dev_sck_writev_stateless (mio_dev_t* dev, const mio_iovec_t* iov, mio_iolen_t* iovcnt, const mio_devaddr_t* dstaddr)
|
||||||
{
|
{
|
||||||
mio_t* mio = dev->mio;
|
mio_t* mio = dev->mio;
|
||||||
@ -900,7 +902,7 @@ static int dev_sck_ioctl (mio_dev_t* dev, int cmd, void* arg)
|
|||||||
|
|
||||||
SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2); /* no outdated SSLv2 by default */
|
SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2); /* no outdated SSLv2 by default */
|
||||||
|
|
||||||
rdev->tmout = bnd->accept_tmout;
|
rdev->tmout = bnd->ssl_accept_tmout;
|
||||||
#else
|
#else
|
||||||
mio_seterrnum (mio, MIO_ENOIMPL);
|
mio_seterrnum (mio, MIO_ENOIMPL);
|
||||||
return -1;
|
return -1;
|
||||||
@ -923,6 +925,7 @@ static int dev_sck_ioctl (mio_dev_t* dev, int cmd, void* arg)
|
|||||||
rdev->ssl_ctx = ssl_ctx;
|
rdev->ssl_ctx = ssl_ctx;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (bnd->options & MIO_DEV_SCK_BIND_LENIENT) rdev->state |= MIO_DEV_SCK_LENIENT;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -931,7 +934,6 @@ static int dev_sck_ioctl (mio_dev_t* dev, int cmd, void* arg)
|
|||||||
mio_dev_sck_connect_t* conn = (mio_dev_sck_connect_t*)arg;
|
mio_dev_sck_connect_t* conn = (mio_dev_sck_connect_t*)arg;
|
||||||
struct sockaddr* sa = (struct sockaddr*)&conn->remoteaddr;
|
struct sockaddr* sa = (struct sockaddr*)&conn->remoteaddr;
|
||||||
mio_scklen_t sl;
|
mio_scklen_t sl;
|
||||||
mio_skad_t localaddr;
|
|
||||||
int x;
|
int x;
|
||||||
#if defined(USE_SSL)
|
#if defined(USE_SSL)
|
||||||
SSL_CTX* ssl_ctx = MIO_NULL;
|
SSL_CTX* ssl_ctx = MIO_NULL;
|
||||||
@ -1488,8 +1490,17 @@ static int dev_evcb_sck_ready_stateful (mio_dev_t* dev, int events)
|
|||||||
}
|
}
|
||||||
else if (events & MIO_DEV_EVENT_IN)
|
else if (events & MIO_DEV_EVENT_IN)
|
||||||
{
|
{
|
||||||
|
if (rdev->state & MIO_DEV_SCK_LENIENT)
|
||||||
|
{
|
||||||
|
accept_incoming_connection(rdev);
|
||||||
|
return 0; /* return ok to the core regardless of accept()'s result */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* [NOTE] if the accept operation fails, the core also kills this listening device. */
|
||||||
return accept_incoming_connection(rdev);
|
return accept_incoming_connection(rdev);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return 0; /* success but don't invoke on_read() */
|
return 0; /* success but don't invoke on_read() */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user