Changes

Jump to navigation Jump to search
2,478 bytes removed ,  19:48, 9 February 2019
m
Line 1: Line 1:  
This page describes step-by-step how to play with TCP dumping and restoring.
 
This page describes step-by-step how to play with TCP dumping and restoring.
 +
 +
__TOC__
    
== Compile and run simple TCP client and server ==
 
== Compile and run simple TCP client and server ==
 
The below program is a simple echo server and a client, that pings server with increasing numbers once a second. In this howto we will dump and restore the client part.
 
The below program is a simple echo server and a client, that pings server with increasing numbers once a second. In this howto we will dump and restore the client part.
<pre>
+
{| class="mw-collapsible mw-collapsed wikitable"
#include <sys/socket.h>
+
! <code>tcp-howto.c</code>
#include <linux/types.h>
+
|-
#include <sys/types.h>
+
| {{:Simple_TCP_pair/tcp-howto.c}}
#include <arpa/inet.h>
+
|}
#include <unistd.h>
  −
#include <string.h>
  −
#include <stdlib.h>
  −
#include <stdio.h>
  −
#include <signal.h>
  −
 
  −
static int serve_new_conn(int sk)
  −
{
  −
int rd, wr;
  −
char buf[1024];
  −
 
  −
printf("New connection\n");
  −
 
  −
while (1) {
  −
rd = read(sk, buf, sizeof(buf));
  −
if (!rd)
  −
break;
  −
 
  −
if (rd < 0) {
  −
perror("Can't read socket");
  −
return 1;
  −
}
  −
 
  −
wr = 0;
  −
while (wr < rd) {
  −
int w;
  −
 
  −
w = write(sk, buf + wr, rd - wr);
  −
if (w <= 0) {
  −
perror("Can't write socket");
  −
return 1;
  −
}
  −
 
  −
wr += w;
  −
}
  −
}
  −
 
  −
printf("Done\n");
  −
return 0;
  −
}
  −
 
  −
static int main_srv(int argc, char **argv)
  −
{
  −
int sk, port, ret;
  −
struct sockaddr_in addr;
  −
 
  −
/*
  −
* Let kids die themselves
  −
*/
  −
 
  −
signal(SIGCHLD, SIG_IGN);
  −
 
  −
sk = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  −
if (sk < 0) {
  −
perror("Can't create socket");
  −
return -1;
  −
}
  −
 
  −
port = atoi(argv[1]);
  −
memset(&addr, 0, sizeof(addr));
  −
addr.sin_family = AF_INET;
  −
addr.sin_addr.s_addr = htonl(INADDR_ANY);
  −
addr.sin_port = htons(port);
  −
 
  −
printf("Binding to port %d\n", port);
  −
 
  −
ret = bind(sk, (struct sockaddr *)&addr, sizeof(addr));
  −
if (ret < 0) {
  −
perror("Can't bind socket");
  −
return -1;
  −
}
  −
 
  −
ret = listen(sk, 16);
  −
if (ret < 0) {
  −
perror("Can't put sock to listen");
  −
return -1;
  −
}
     −
printf("Waiting for connections\n");
+
Compile it and run the server:
while (1) {
  −
int ask, pid;
     −
ask = accept(sk, NULL, NULL);
+
# ./tcp-howto <some-port>
if (ask < 0) {
  −
perror("Can't accept new conn");
  −
return -1;
  −
}
     −
pid = fork();
+
On another terminal (for better output readability) run the client:
if (pid < 0) {
  −
perror("Can't fork");
  −
return -1;
  −
}
     −
if (pid > 0)
+
# ./tcp-howto 127.0.0.1 <some-port>
close(ask);
  −
else {
  −
close(sk);
  −
ret = serve_new_conn(ask);
  −
exit(ret);
  −
}
  −
}
  −
}
  −
 
  −
static int main_cl(int argc, char **argv)
  −
{
  −
int sk, port, ret, val = 1, rval;
  −
struct sockaddr_in addr;
  −
 
  −
sk = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  −
if (sk < 0) {
  −
perror("Can't create socket");
  −
return -1;
  −
}
  −
 
  −
port = atoi(argv[2]);
  −
printf("Connecting to %s:%d\n", argv[1], port);
  −
memset(&addr, 0, sizeof(addr));
  −
addr.sin_family = AF_INET;
  −
ret = inet_aton(argv[1], &addr.sin_addr);
  −
if (ret < 0) {
  −
perror("Can't convert addr");
  −
return -1;
  −
}
  −
addr.sin_port = htons(port);
  −
 
  −
ret = connect(sk, (struct sockaddr *)&addr, sizeof(addr));
  −
if (ret < 0) {
  −
perror("Can't connect");
  −
return -1;
  −
}
  −
 
  −
while (1) {
  −
write(sk, &val, sizeof(val));
  −
rval = -1;
  −
read(sk, &rval, sizeof(rval));
  −
printf("PP %d -> %d\n", val, rval);
  −
sleep(2);
  −
val++;
  −
}
  −
}
  −
 
  −
int main(int argc, char **argv)
  −
{
  −
if (argc == 2)
  −
return main_srv(argc, argv);
  −
else if (argc == 3)
  −
return main_cl(argc, argv);
  −
 
  −
printf("Bad usage\n");
  −
return 1;
  −
}
  −
</pre>
  −
 
  −
So compile it and run server
  −
<pre>
  −
# ./tcp-howto <some-port>
  −
</pre>
  −
and on another terminal (for better output readability) -- the client
  −
<pre>
  −
# ./tcp-howto 127.0.0.1 <some-port>
  −
</pre>
      
== Try to dump the client ==
 
== Try to dump the client ==
 
Create a directory for images (<code>img-dir/</code> below) and dump the client
 
Create a directory for images (<code>img-dir/</code> below) and dump the client
 
<pre>
 
<pre>
# crtools dump --tree <tcp-howto-client-pid> --images-dir img-dir/ -v 4 -o dump.log --shell-job --tcp-established
+
# criu dump --tree <tcp-howto-client-pid> --images-dir img-dir/ -v4 -o dump.log --shell-job --tcp-established
 
</pre>
 
</pre>
   Line 184: Line 32:  
It's done like this
 
It's done like this
 
<pre>
 
<pre>
# crtools restore --tree <tcp-howto-client-pid> --images-dir img-dir/ -v 4 -o rst.log --shell-job --tcp-established
+
# criu restore --images-dir img-dir/ -v4 -o rst.log --shell-job --tcp-established
 
</pre>
 
</pre>
   −
That's it. After this in the terminal you launched crtools from you should see the contunuing output of the tcp client.
+
That's it. After this in the terminal you launched criu from you should see the continuing output of the tcp client.
 +
 
 +
== See also ==
 +
 
 +
* [[TCP connection]]
 +
 
 +
[[Category:HOWTO]]
 +
[[Category:Sockets]]

Navigation menu