* [PATCH] cryo: Improve socket support: add UDP and IPv6 [not found] <20080616153819.192784006@theryb.frec.bull.fr> @ 2008-06-16 15:38 ` Benjamin Thery [not found] ` <20080616153825.210138850-4vkkeT0zb4ZEtYaxpPmRp1aPQRlvutdw@public.gmane.org> 0 siblings, 1 reply; 3+ messages in thread From: Benjamin Thery @ 2008-06-16 15:38 UTC (permalink / raw) To: Serge E. Hallyn; +Cc: Containers, Benjamin Thery Today, I played a bit with inet sockets and cryo. With few modifications I managed to "checkpoint-restart" programs that use UDP sockets to listen and send data. This patch improves socket checkpointing in cryo: * Save/restore socket family: we can checkpoint IPv6 sockets now. * Save/restore socket type: we can checkpoint UDP sockets too. Simple test programs for UDP sockets available upon request :) Regards, Benjamin Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org> --- cr.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 50 insertions(+), 13 deletions(-) Index: cryodev/cr.c =================================================================== --- cryodev.orig/cr.c +++ cryodev/cr.c @@ -67,11 +67,15 @@ int pagesize = 0; typedef struct isockinfo_t { int fdnum; - int type; /* socket type: UDP, TCP */ + int type; /* socket type: SOCK_STREAM, SOCK_DGRAM */ + int family; /* socket family: AF_INET, AF_INET6 */ int mode; /* bind, listen, connect */ int opt; /* various sockopt */ int backlog; /* for listen(2) */ - struct sockaddr_in locaddr; /* for bind(2) */ + union { + struct sockaddr_in saddr4; + struct sockaddr_in6 saddr6; + } locaddr; /* for bind(2) */ char tcpstate[TPI_LEN]; } isockinfo_t; @@ -179,7 +183,7 @@ int getmaps(pid_t pid, memseg_t **p) int getsockinfo(pid_t pid, pinfo_t *pi, int num) { - struct sockaddr name; + struct sockaddr_storage name; int namelen = (int)sizeof(name), ret = 0; int tpi_len = TPI_LEN; int flag, flaglen; @@ -188,9 +192,11 @@ int getsockinfo(pid_t pid, pinfo_t *pi, /* get socketname and see if it is an unix or an inet socket */ memset(&name, 0, sizeof(name)); PT_GETSOCKNAME(pid, num, &name, &namelen); - t_d(name.sa_family); + t_d(name.ss_family); - if (name.sa_family != (sa_family_t)AF_INET) return ret; + if (name.ss_family != (sa_family_t)AF_INET && + name.ss_family != (sa_family_t)AF_INET6) + return ret; if (! (pi->si = (isockinfo_t *)realloc(pi->si, sizeof(isockinfo_t) * (pi->ns+1)))) return -1; psi = &pi->si[pi->ns]; @@ -198,11 +204,25 @@ int getsockinfo(pid_t pid, pinfo_t *pi, //pi->si[pi->ns].fdnum = num; psi->fdnum = num; + psi->family = name.ss_family; psi->mode = ISOCK_UNKNOWN; - memcpy((void *)&psi->locaddr, (void *)&name, sizeof(name)); - if (psi->locaddr.sin_addr.s_addr != 0 || psi->locaddr.sin_port != 0) psi->mode |= ISOCK_BIND; - + memcpy((void *)&psi->locaddr, (void *)&name, namelen); + + if ((psi->family == AF_INET && + (psi->locaddr.saddr4.sin_addr.s_addr != INADDR_ANY || + psi->locaddr.saddr4.sin_port != 0)) || + (psi->family == AF_INET6 && + (memcmp(&psi->locaddr.saddr6.sin6_addr, &in6addr_any, 16) != 0 || + psi->locaddr.saddr6.sin6_port != 0))) + psi->mode |= ISOCK_BIND; + + flag = 0; + flaglen = (int)sizeof(flag); + PT_GETSOCKOPT(pid, num, SOL_SOCKET, SO_TYPE, &flag, &flaglen); + if (flag) + psi->type = flag; + flag = 0; flaglen = (int)sizeof(flag); PT_GETSOCKOPT(pid, num, SOL_SOCKET, SO_REUSEADDR, &flag, &flaglen); @@ -866,6 +886,7 @@ int restore_sock(int fd, pid_t pid) int sock; size_t bufsz; isockinfo_t *isockinfo = NULL; + int len; for (;;) { read_item(fd, item, sizeof(item), &buf, &bufsz); @@ -873,20 +894,36 @@ int restore_sock(int fd, pid_t pid) else ITEM_SET(isockinfo, isockinfo_t); else break; // unknown item - t_d(sock = PT_SOCKET(pid, AF_INET, SOCK_STREAM, 0)); + t_d(sock = PT_SOCKET(pid, isockinfo->family, isockinfo->type, 0)); if (sock < 0) { ERROR("PT_SOCKET(%d, %d, %d, %d) errno=%d: %s", - pid, AF_INET, SOCK_STREAM, 0, sock, strerror(-sock)); + pid, isockinfo->family, isockinfo->type, 0, + sock, strerror(-sock)); } t_d(PT_DUP2(pid, sock, isockinfo->fdnum)); if (sock != isockinfo->fdnum) t_d(PT_CLOSE(pid, sock)); if (isockinfo->mode & ISOCK_BIND) { + struct sockaddr *sa; struct sockaddr_in sin; + struct sockaddr_in6 sin6; - memcpy((void *)&sin, (void *)&isockinfo->locaddr, sizeof(sin)); - if (isockinfo->mode & ISOCK_CONNECT) sin.sin_port = htons(0); - t_d(PT_BIND(pid, isockinfo->fdnum, &sin, sizeof(sin))); + if (isockinfo->family == AF_INET) { + len = sizeof(sin); + memcpy((void *)&sin, + (void *)&isockinfo->locaddr.saddr4, len); + if (isockinfo->mode & ISOCK_CONNECT) + sin6.sin6_port = htons(0); + sa = (struct sockaddr *) &sin; + } else { + len = sizeof(sin6); + memcpy((void *)&sin6, + (void *)&isockinfo->locaddr.saddr6, len); + if (isockinfo->mode & ISOCK_CONNECT) + sin.sin_port = htons(0); + sa = (struct sockaddr *) &sin6; + } + t_d(PT_BIND(pid, isockinfo->fdnum, sa, len)); } if (isockinfo->mode & ISOCK_LISTEN) { t_d(PT_LISTEN(pid, isockinfo->fdnum, 64)); //FIXME: get backlog from TPI_INFO -- ^ permalink raw reply [flat|nested] 3+ messages in thread
[parent not found: <20080616153825.210138850-4vkkeT0zb4ZEtYaxpPmRp1aPQRlvutdw@public.gmane.org>]
* Re: [PATCH] cryo: Improve socket support: add UDP and IPv6 [not found] ` <20080616153825.210138850-4vkkeT0zb4ZEtYaxpPmRp1aPQRlvutdw@public.gmane.org> @ 2008-06-16 16:22 ` Dave Hansen 2008-06-16 18:22 ` Benjamin Thery 0 siblings, 1 reply; 3+ messages in thread From: Dave Hansen @ 2008-06-16 16:22 UTC (permalink / raw) To: Benjamin Thery; +Cc: Containers On Mon, 2008-06-16 at 17:38 +0200, Benjamin Thery wrote: > Today, I played a bit with inet sockets and cryo. With few modifications > I managed to "checkpoint-restart" programs that use UDP sockets to listen > and send data. > > This patch improves socket checkpointing in cryo: > * Save/restore socket family: we can checkpoint IPv6 sockets now. > * Save/restore socket type: we can checkpoint UDP sockets too. > > Simple test programs for UDP sockets available upon request :) > > Regards, > Benjamin > > Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org> > --- > cr.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++------------- > 1 file changed, 50 insertions(+), 13 deletions(-) > > Index: cryodev/cr.c > =================================================================== > --- cryodev.orig/cr.c > +++ cryodev/cr.c > @@ -67,11 +67,15 @@ int pagesize = 0; > > typedef struct isockinfo_t { > int fdnum; > - int type; /* socket type: UDP, TCP */ > + int type; /* socket type: SOCK_STREAM, SOCK_DGRAM */ > + int family; /* socket family: AF_INET, AF_INET6 */ > int mode; /* bind, listen, connect */ > int opt; /* various sockopt */ > int backlog; /* for listen(2) */ > - struct sockaddr_in locaddr; /* for bind(2) */ > + union { > + struct sockaddr_in saddr4; > + struct sockaddr_in6 saddr6; > + } locaddr; /* for bind(2) */ > char tcpstate[TPI_LEN]; > } isockinfo_t; > > @@ -179,7 +183,7 @@ int getmaps(pid_t pid, memseg_t **p) > > int getsockinfo(pid_t pid, pinfo_t *pi, int num) > { > - struct sockaddr name; > + struct sockaddr_storage name; > int namelen = (int)sizeof(name), ret = 0; > int tpi_len = TPI_LEN; > int flag, flaglen; > @@ -188,9 +192,11 @@ int getsockinfo(pid_t pid, pinfo_t *pi, > /* get socketname and see if it is an unix or an inet socket */ > memset(&name, 0, sizeof(name)); > PT_GETSOCKNAME(pid, num, &name, &namelen); > - t_d(name.sa_family); > + t_d(name.ss_family); > > - if (name.sa_family != (sa_family_t)AF_INET) return ret; > + if (name.ss_family != (sa_family_t)AF_INET && > + name.ss_family != (sa_family_t)AF_INET6) > + return ret; > > if (! (pi->si = (isockinfo_t *)realloc(pi->si, sizeof(isockinfo_t) * (pi->ns+1)))) return -1; > psi = &pi->si[pi->ns]; > @@ -198,11 +204,25 @@ int getsockinfo(pid_t pid, pinfo_t *pi, > > //pi->si[pi->ns].fdnum = num; > psi->fdnum = num; > + psi->family = name.ss_family; > > psi->mode = ISOCK_UNKNOWN; > - memcpy((void *)&psi->locaddr, (void *)&name, sizeof(name)); > - if (psi->locaddr.sin_addr.s_addr != 0 || psi->locaddr.sin_port != 0) psi->mode |= ISOCK_BIND; > - > + memcpy((void *)&psi->locaddr, (void *)&name, namelen); > + > + if ((psi->family == AF_INET && > + (psi->locaddr.saddr4.sin_addr.s_addr != INADDR_ANY || > + psi->locaddr.saddr4.sin_port != 0)) || > + (psi->family == AF_INET6 && > + (memcmp(&psi->locaddr.saddr6.sin6_addr, &in6addr_any, 16) != 0 || > + psi->locaddr.saddr6.sin6_port != 0))) > + psi->mode |= ISOCK_BIND; Could you put this into a little helper? It is getting a little convoluted. > + flag = 0; > + flaglen = (int)sizeof(flag); > + PT_GETSOCKOPT(pid, num, SOL_SOCKET, SO_TYPE, &flag, &flaglen); > + if (flag) > + psi->type = flag; > + > flag = 0; > flaglen = (int)sizeof(flag); Why are you casting this? > PT_GETSOCKOPT(pid, num, SOL_SOCKET, SO_REUSEADDR, &flag, &flaglen); > @@ -866,6 +886,7 @@ int restore_sock(int fd, pid_t pid) > int sock; > size_t bufsz; > isockinfo_t *isockinfo = NULL; > + int len; > > for (;;) { > read_item(fd, item, sizeof(item), &buf, &bufsz); > @@ -873,20 +894,36 @@ int restore_sock(int fd, pid_t pid) > else ITEM_SET(isockinfo, isockinfo_t); > else break; // unknown item > > - t_d(sock = PT_SOCKET(pid, AF_INET, SOCK_STREAM, 0)); > + t_d(sock = PT_SOCKET(pid, isockinfo->family, isockinfo->type, 0)); > if (sock < 0) { > ERROR("PT_SOCKET(%d, %d, %d, %d) errno=%d: %s", > - pid, AF_INET, SOCK_STREAM, 0, sock, strerror(-sock)); > + pid, isockinfo->family, isockinfo->type, 0, > + sock, strerror(-sock)); > } > t_d(PT_DUP2(pid, sock, isockinfo->fdnum)); > if (sock != isockinfo->fdnum) t_d(PT_CLOSE(pid, sock)); > > if (isockinfo->mode & ISOCK_BIND) { > + struct sockaddr *sa; > struct sockaddr_in sin; > + struct sockaddr_in6 sin6; > > - memcpy((void *)&sin, (void *)&isockinfo->locaddr, sizeof(sin)); > - if (isockinfo->mode & ISOCK_CONNECT) sin.sin_port = htons(0); > - t_d(PT_BIND(pid, isockinfo->fdnum, &sin, sizeof(sin))); > + if (isockinfo->family == AF_INET) { > + len = sizeof(sin); > + memcpy((void *)&sin, > + (void *)&isockinfo->locaddr.saddr4, len); I see that these casts were there already, but could we kill them since you're touching it now? > + if (isockinfo->mode & ISOCK_CONNECT) > + sin6.sin6_port = htons(0); > + sa = (struct sockaddr *) &sin; > + } else { How about an explicit check for AF_INET6 here? > + len = sizeof(sin6); > + memcpy((void *)&sin6, > + (void *)&isockinfo->locaddr.saddr6, len); > + if (isockinfo->mode & ISOCK_CONNECT) > + sin.sin_port = htons(0); > + sa = (struct sockaddr *) &sin6; > + } > + t_d(PT_BIND(pid, isockinfo->fdnum, sa, len)); -- Dave ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] cryo: Improve socket support: add UDP and IPv6 2008-06-16 16:22 ` Dave Hansen @ 2008-06-16 18:22 ` Benjamin Thery 0 siblings, 0 replies; 3+ messages in thread From: Benjamin Thery @ 2008-06-16 18:22 UTC (permalink / raw) To: Dave Hansen; +Cc: Containers Dave Hansen <dave-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org> a écrit : > On Mon, 2008-06-16 at 17:38 +0200, Benjamin Thery wrote: >> Today, I played a bit with inet sockets and cryo. With few modifications >> I managed to "checkpoint-restart" programs that use UDP sockets to listen >> and send data. >> >> This patch improves socket checkpointing in cryo: >> * Save/restore socket family: we can checkpoint IPv6 sockets now. >> * Save/restore socket type: we can checkpoint UDP sockets too. >> >> Simple test programs for UDP sockets available upon request :) >> >> Regards, >> Benjamin >> >> Signed-off-by: Benjamin Thery <benjamin.thery-6ktuUTfB/bM@public.gmane.org> >> --- >> cr.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++------------- >> 1 file changed, 50 insertions(+), 13 deletions(-) >> >> Index: cryodev/cr.c >> =================================================================== >> --- cryodev.orig/cr.c >> +++ cryodev/cr.c >> @@ -67,11 +67,15 @@ int pagesize = 0; >> >> typedef struct isockinfo_t { >> int fdnum; >> - int type; /* socket type: UDP, TCP */ >> + int type; /* socket type: SOCK_STREAM, SOCK_DGRAM */ >> + int family; /* socket family: AF_INET, AF_INET6 */ >> int mode; /* bind, listen, connect */ >> int opt; /* various sockopt */ >> int backlog; /* for listen(2) */ >> - struct sockaddr_in locaddr; /* for bind(2) */ >> + union { >> + struct sockaddr_in saddr4; >> + struct sockaddr_in6 saddr6; >> + } locaddr; /* for bind(2) */ >> char tcpstate[TPI_LEN]; >> } isockinfo_t; >> >> @@ -179,7 +183,7 @@ int getmaps(pid_t pid, memseg_t **p) >> >> int getsockinfo(pid_t pid, pinfo_t *pi, int num) >> { >> - struct sockaddr name; >> + struct sockaddr_storage name; >> int namelen = (int)sizeof(name), ret = 0; >> int tpi_len = TPI_LEN; >> int flag, flaglen; >> @@ -188,9 +192,11 @@ int getsockinfo(pid_t pid, pinfo_t *pi, >> /* get socketname and see if it is an unix or an inet socket */ >> memset(&name, 0, sizeof(name)); >> PT_GETSOCKNAME(pid, num, &name, &namelen); >> - t_d(name.sa_family); >> + t_d(name.ss_family); >> >> - if (name.sa_family != (sa_family_t)AF_INET) return ret; >> + if (name.ss_family != (sa_family_t)AF_INET && >> + name.ss_family != (sa_family_t)AF_INET6) >> + return ret; >> >> if (! (pi->si = (isockinfo_t *)realloc(pi->si, >> sizeof(isockinfo_t) * (pi->ns+1)))) return -1; >> psi = &pi->si[pi->ns]; >> @@ -198,11 +204,25 @@ int getsockinfo(pid_t pid, pinfo_t *pi, >> >> //pi->si[pi->ns].fdnum = num; >> psi->fdnum = num; >> + psi->family = name.ss_family; >> >> psi->mode = ISOCK_UNKNOWN; >> - memcpy((void *)&psi->locaddr, (void *)&name, sizeof(name)); >> - if (psi->locaddr.sin_addr.s_addr != 0 || psi->locaddr.sin_port != >> 0) psi->mode |= ISOCK_BIND; >> - >> + memcpy((void *)&psi->locaddr, (void *)&name, namelen); >> + >> + if ((psi->family == AF_INET && >> + (psi->locaddr.saddr4.sin_addr.s_addr != INADDR_ANY || >> + psi->locaddr.saddr4.sin_port != 0)) || >> + (psi->family == AF_INET6 && >> + (memcmp(&psi->locaddr.saddr6.sin6_addr, &in6addr_any, 16) != 0 || >> + psi->locaddr.saddr6.sin6_port != 0))) >> + psi->mode |= ISOCK_BIND; > > Could you put this into a little helper? It is getting a little > convoluted. Yes, sure I can do that. >> + flag = 0; >> + flaglen = (int)sizeof(flag); >> + PT_GETSOCKOPT(pid, num, SOL_SOCKET, SO_TYPE, &flag, &flaglen); >> + if (flag) >> + psi->type = flag; >> + >> flag = 0; >> flaglen = (int)sizeof(flag); > > Why are you casting this? Um... it was there already. I dumbly copied the code. :) > >> PT_GETSOCKOPT(pid, num, SOL_SOCKET, SO_REUSEADDR, &flag, &flaglen); >> @@ -866,6 +886,7 @@ int restore_sock(int fd, pid_t pid) >> int sock; >> size_t bufsz; >> isockinfo_t *isockinfo = NULL; >> + int len; >> >> for (;;) { >> read_item(fd, item, sizeof(item), &buf, &bufsz); >> @@ -873,20 +894,36 @@ int restore_sock(int fd, pid_t pid) >> else ITEM_SET(isockinfo, isockinfo_t); >> else break; // unknown item >> >> - t_d(sock = PT_SOCKET(pid, AF_INET, SOCK_STREAM, 0)); >> + t_d(sock = PT_SOCKET(pid, isockinfo->family, isockinfo->type, 0)); >> if (sock < 0) { >> ERROR("PT_SOCKET(%d, %d, %d, %d) errno=%d: %s", >> - pid, AF_INET, SOCK_STREAM, 0, sock, strerror(-sock)); >> + pid, isockinfo->family, isockinfo->type, 0, >> + sock, strerror(-sock)); >> } >> t_d(PT_DUP2(pid, sock, isockinfo->fdnum)); >> if (sock != isockinfo->fdnum) t_d(PT_CLOSE(pid, sock)); >> >> if (isockinfo->mode & ISOCK_BIND) { >> + struct sockaddr *sa; >> struct sockaddr_in sin; >> + struct sockaddr_in6 sin6; >> >> - memcpy((void *)&sin, (void *)&isockinfo->locaddr, sizeof(sin)); >> - if (isockinfo->mode & ISOCK_CONNECT) sin.sin_port = htons(0); >> - t_d(PT_BIND(pid, isockinfo->fdnum, &sin, sizeof(sin))); >> + if (isockinfo->family == AF_INET) { >> + len = sizeof(sin); >> + memcpy((void *)&sin, >> + (void *)&isockinfo->locaddr.saddr4, len); > > I see that these casts were there already, but could we kill them since > you're touching it now? Sure. >> + if (isockinfo->mode & ISOCK_CONNECT) >> + sin6.sin6_port = htons(0); >> + sa = (struct sockaddr *) &sin; >> + } else { > > How about an explicit check for AF_INET6 here? It isn't necessary as we're in restart and we only checkpointed the family we know about. But I agree with you, it is misleading. I'll add an explicit check. Thanks for the review. -Benjamin > >> + len = sizeof(sin6); >> + memcpy((void *)&sin6, >> + (void *)&isockinfo->locaddr.saddr6, len); >> + if (isockinfo->mode & ISOCK_CONNECT) >> + sin.sin_port = htons(0); >> + sa = (struct sockaddr *) &sin6; >> + } >> + t_d(PT_BIND(pid, isockinfo->fdnum, sa, len)); > > -- Dave > > > ---------------------------------------------------------------- This message was sent using IMP, the Internet Messaging Program. ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2008-06-16 18:22 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20080616153819.192784006@theryb.frec.bull.fr>
2008-06-16 15:38 ` [PATCH] cryo: Improve socket support: add UDP and IPv6 Benjamin Thery
[not found] ` <20080616153825.210138850-4vkkeT0zb4ZEtYaxpPmRp1aPQRlvutdw@public.gmane.org>
2008-06-16 16:22 ` Dave Hansen
2008-06-16 18:22 ` Benjamin Thery
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.