File: net_lock_socket_iptables.hook

package info (click to toggle)
criu 4.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 11,500 kB
  • sloc: ansic: 139,280; python: 7,484; sh: 3,824; java: 2,799; makefile: 2,659; asm: 1,137; perl: 206; xml: 117; exp: 45
file content (88 lines) | stat: -rwxr-xr-x 2,513 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#!/usr/bin/env python3

import socket
import time
import sys
import os

PORT = 8880
TIMEOUT = 0.1
INTERNAL_SERVER = "\0internal_server"
SYNCFILE = "zdtm/static/socket_lock.sync"

def wait_server_addr():
    for _ignore in range(3):
        try:
            with open(SYNCFILE, "r") as f:
                addr = f.read(4)
            os.remove(SYNCFILE)

            if addr == "ipv4":
                return "127.0.0.1"

            if addr == "ipv6":
                return "::1"

            raise Exception("Invalid address type")
        except IOError:
            time.sleep(1)

    raise TimeoutError("Sync timeout: file ({}) not found".format(SYNCFILE))

if sys.argv[1] == "--post-start":
    internal_sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    internal_sock.bind(INTERNAL_SERVER)
    internal_sock.listen(1)

    # Wait for test server to be ready
    server_addr = wait_server_addr()

    pid = os.fork()
    if pid == 0:
        os.setsid()  # Detach from parent

        test_sock = socket.create_connection((server_addr, PORT), TIMEOUT)

        while True:
            internal_conn, _ignore = internal_sock.accept()
            hook = internal_conn.recv(100).decode()

            try:
                if hook == "--pre-dump":
                    test_sock.sendall(str.encode("A"))

                elif hook == "--pre-restore":
                    # Data sent while TCP socket is "locked" should be retransmitted.
                    test_sock.sendall(str.encode("B"))

                elif hook == "--post-restore":
                    test_sock.sendall(str.encode("C"))

                elif hook == "--clean":
                    break

                internal_conn.sendall(str.encode("pass"))
            except Exception as e:
                internal_conn.sendall(str.encode("fail"))
                raise e
            finally:
                internal_conn.close()

    internal_sock.close()

if sys.argv[1] in ["--pre-dump", "--pre-restore", "--post-restore"]:
    internal_conn = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    internal_conn.connect(INTERNAL_SERVER)
    internal_conn.sendall(str.encode(sys.argv[1]))

    status = internal_conn.recv(100).decode()
    if status != "pass":
        sys.exit(1)

    internal_conn.close()

if sys.argv[1] == "--clean":
    # Clean up internal server
    internal_conn = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    internal_conn.connect(INTERNAL_SERVER)
    internal_conn.sendall(str.encode(sys.argv[1]))