Ticket #781: tst-xapian_remote.cc

File tst-xapian_remote.cc, 2.2 KB (added by German M. Bravo, 6 years ago)

Reproducer of the socket leak

Line 
1/*
2c++ -std=c++14 -o tst-xapian_remote -lxapian tst-xapian_remote.cc && ./tst-xapian_remote
3*/
4
5#include <iostream>
6#include <string>
7#include <cstdio>
8#include <cassert>
9#include <thread>
10
11#include <errno.h>
12#include <unistd.h>
13#include <netdb.h>
14#include <sys/socket.h>
15#include <netinet/in.h>
16
17#include "xapian.h"
18
19constexpr const int port = 5000;
20
21
22void fake_server_process(int sock) {
23 char buf[100];
24 // Send REPLY_UPDATE
25 if (write(sock, "\x00" "\x2e" "\x27\x00\x05\xff\x0d\x9a\x0d\x15\x31\x6d" "8c96f317-76c4-421e-bacb-3db0e076b79e", 48) == -1) {
26 perror("ERROR writing to socket");
27 return;
28 }
29 // Receive message
30 auto size = read(sock, buf, sizeof(buf));
31 if (size == -1) {
32 perror("ERROR reading from socket");
33 return;
34 }
35 // Send REPLY_EXCEPTION with a fake DatabaseError
36 if (write(sock, "\x01" "\x1e" "\x04" "\x0c" "Fake context" "\x0a" "Fake error" "Error", 32) == -1) {
37 perror("ERROR writing to socket");
38 return;
39 }
40 // Socket not closed on the server side
41}
42
43
44void fake_server() {
45 int portno, clilen;
46 int n, pid;
47
48 int listen_socket = socket(AF_INET, SOCK_STREAM, 0);
49 if (listen_socket == -1) {
50 perror("ERROR opening socket");
51 exit(1);
52 }
53
54 int optval = 1;
55 if (setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, (char *)(&optval), sizeof(optval)) == -1) {
56 perror("ERROR opening socket");
57 exit(1);
58 }
59
60 struct sockaddr_in serv_addr;
61 memset(&serv_addr, 0, sizeof(serv_addr));
62 serv_addr.sin_family = AF_INET;
63 serv_addr.sin_addr.s_addr = INADDR_ANY;
64 serv_addr.sin_port = htons(port);
65
66 if (bind(listen_socket, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) == -1) {
67 perror("ERROR on binding");
68 exit(1);
69 }
70
71 listen(listen_socket, 5);
72
73 struct sockaddr_in cli_addr;
74 socklen_t address_len = sizeof(cli_addr);
75
76 while (true) {
77 int sock = accept(listen_socket, (struct sockaddr *)&cli_addr, &address_len);
78 if (sock != -1) {
79 std::thread server(fake_server_process, sock);
80 server.detach();
81 }
82 }
83}
84
85
86int main() {
87 std::thread server(fake_server);
88
89 while (true) {
90 try {
91 auto wsdb = Xapian::Remote::open_writable("localhost", port, 10000, 10000, Xapian::DB_CREATE_OR_OPEN);
92 } catch (const Xapian::Error& exc) {
93 std::cerr << exc.get_description() << std::endl;
94 }
95 }
96
97 return 0;
98}