LINUX.ORG.RU

3
Всего сообщений: 40

Что такое local/unix/inet в конфигах Postfix и OpenDKIM?

В Postfix и OpenDKIM в конфигах можно указать вот такие настройки для TCP и UNIX сокетов:


//1
Socket local:/var/spool/postfix/opendkim/opendkim.sock

//2
smtpd_milters = local:/etc/postfix/opendkim/opendkim.sock
non_smtpd_milters = local:/etc/postfix/opendkim/opendkim.sock

//3
smtpd_milters = unix:/etc/postfix/opendkim/opendkim.sock
non_smtpd_milters = unix:/etc/postfix/opendkim/opendkim.sock

//4
smtpd_milters = inet:localhost:8891
non_smtpd_milters = $smtpd_milters

Я не могу найти инфу про эти префиксы - local, unix, inet. Как они называются в линуксе? Какие бывают? И где почитать про них?

В чём разница между unix и local?

 , , ,

Normady ()

Отправка днных с указанного сетевого интерфейса

Пишу простой сетевой клиент для отправки tcp по книге Стивенса. И у меня возник вопрос. Как указать сетевой интерфейс, через который должна происходить отправка данных? (у меня в системе несколько сетевых карт eth0 eth1 eth2 eth3)

 

gib85159 ()

Сокеты

Здравствуйте! Помогите, пожалуйста со следующей проблемой. У меня есть готовый код, описывающий взаимодействие клиент-сервер. Но он работает как общий чат.То есть при отправке сообщения на сервер это сообщение видят все клиенты. Этот код нужно доработать, так чтобы клиент мог выбирать адресата из списка всех клиентов и общаться только с ним. Можете подсказать как это организовать? Или какие ошибки исправить в коде?

Код сервера:

include <unistd.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <strings.h>

#include <poll.h>
#define IPADDRESS "127.0.0.1"
#define PORT 6666
#define MAXLINE 1024
#define LISTENQ 5
#define OPEN_MAX 1000
#define INFTIM -1

int bind_and_listen()
{
	int serverfd;
	struct sockaddr_in my_addr;
	unsigned int sin_size;
	if((serverfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
	{
		printf ("error socket");
		return -1;
	}
	printf("socket ok\n");
	my_addr.sin_family = AF_INET;
	my_addr.sin_port = htons(PORT);
	my_addr.sin_addr.s_addr = INADDR_ANY;
	bzero(&(my_addr.sin_zero), 0);
	if(bind(serverfd, (struct sockaddr*)&my_addr, sizeof(struct sockaddr)) == -1)
	{
		printf("error bind");
		return -2;
	}
	printf("bind ok\n");
	if(listen(serverfd, LISTENQ) == -1)
	{
		printf("error listen");
		return -3;
	}
	printf("listen ok\n");
	return serverfd;
}

void do_poll(int listenfd)
{
	int connfd, sockfd;
	struct sockaddr_in cliaddr;
	socklen_t cliaddrlen;
	struct pollfd clientfds[OPEN_MAX];      
	int maxi;
	int sin_port2[5];
	int i,j;
	int nready;
	clientfds[0].fd = listenfd;
	clientfds[0].events = POLLIN;
	for(i = 1; i<OPEN_MAX; i++)
		clientfds[i].fd = -1;
	maxi = 0;

	while(1)
	{
		nready = poll(clientfds, maxi+1, INFTIM);
		if(nready == -1)
		{
			printf("poll error");
			exit(1);
		}
		if(clientfds[0].revents & POLLIN)
		{
			cliaddrlen = sizeof(cliaddr);
			if((connfd = accept(listenfd, (struct sockaddr*)&cliaddr, &cliaddrlen)) <0)
			{
				
					printf("accept error");
					exit(1);
				
			}
			fprintf(stdout, "accept a new client:%s:%d\n", inet_ntoa(cliaddr.sin_addr), cliaddr.sin_port);
			for(i = 1; i<OPEN_MAX; i++)
			{
				if(clientfds[i].fd<0)
				{
					clientfds[i].fd = connfd;
					break;
				}
			}
			if(i == OPEN_MAX)
			{
				fprintf(stderr, "too many clients.\n");
				exit(1);
			}
			sin_port2[i]=cliaddr.sin_port;
			clientfds[i].events = POLLIN;
			maxi = (i>maxi?i:maxi);
			if(--nready<=0)  
				continue;
		}
		
		char buf[MAXLINE];
                char BUF[80];
		
		memset(buf, 0, MAXLINE);
		int readlen = 0;
		for(i = 1; i<maxi; i++)    
		{
			if(clientfds[i].fd<0) continue;
				
			if(clientfds[i].revents & POLLIN)
			{
				readlen = read(clientfds[i].fd, buf, MAXLINE);
				if(readlen == 0)
				{
					close(clientfds[i].fd);
					clientfds[i].fd = -1;
					continue;
				}
				printf("msg is:");
				
				memset(BUF,0,sizeof(BUF));
				sprintf(BUF,"%d :%s",sin_port2[i],buf);
				printf("%s",BUF);
				
                                for(j=1;j<maxi;j++)
				{
				if(i!=j){
				write(clientfds[j].fd, BUF, sizeof(BUF));
				}
				}
	                                
			}
		}
	}
}
int main(int argc, char* argv[])
{
	int listenfd = bind_and_listen();
	if(listenfd<0)
	{
		return 0;
	}
	do_poll(listenfd);
	return 0;
}

Код клиента:


#include<sys/types.h>
#include<sys/socket.h>
#include<unistd.h>
#include<netinet/in.h>

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#include<poll.h>
#define IPADDRESS "127.0.0.1"
#define PORT 20113
#define MAXLINE 1024
#define max(a, b) (a>b)?a:b
static void handle_connection(int sockfd);
int main(int argc, char* argv[])
{
	int connfd = 0;
	int clen = 0;
	struct sockaddr_in client;
	if(argc<2)
	{
		printf("Usage: clientent[server IP address]\n");
		return -1;
	}
	client.sin_family = AF_INET;
	client.sin_port = htons(PORT);
	client.sin_addr.s_addr = inet_addr(argv[1]);
	connfd = socket(AF_INET, SOCK_STREAM, 0);
	if(connfd<0)
	{
		printf("error socket");
		return -1;
	}
	if(connect(connfd, (struct sockaddr*)&client, sizeof(client))<0)
	{
		printf("error connect");
		return -1;
	}
	handle_connection(connfd);
	return 0;
}

static void handle_connection(int sockfd)
{
	char sendline[MAXLINE], recvline[MAXLINE];
	int maxfdp, stdineof;
	struct pollfd pfds[2];
	int n;
	pfds[0].fd = sockfd;
	pfds[0].events = POLLIN;
	pfds[1].fd = STDIN_FILENO;
	pfds[1].events = POLLIN;
	while(1)
	{
		poll(pfds, 2, -1);
		if(pfds[0].revents & POLLIN)
		{
			n = read(sockfd, recvline, MAXLINE);
			if(n == 0)
			{
				fprintf(stderr, "client: server is closed.\n");
				close(sockfd);
			}
			write(STDOUT_FILENO, recvline, n);
		}
		if(pfds[1].revents & POLLIN)
		{
			n = read(STDIN_FILENO, sendline, MAXLINE);
			if(n == 0)
			{
				shutdown(sockfd, SHUT_WR);
				continue;
			}
			write(sockfd, sendline, n);
		}
	}
}

[code = C]

 , , ,

art_em ()

Сетевые пакетные сокеты

Вот для потоковых протоколов, например TCP, сокеты, имеющие функции send/recv полностью адекватны.

Но для датаграммных протоколов, типа UDP, IP, Ethernet, итп функция recv мне кажется совсем неверной по сути. По идее, вместо вызова recv было бы адекватнее из вызывать коллбэк, в который бы передавались данные и длина пришедшего пакета.

На низком уровне собственно так и происходит: сетевая карточка при приходе пакета дергает прерывание и тем самым вызывает обработчик прерывания, входящий в драйвер сетевой карты, который считывает очередной пакет и обрабатывает его.

Это адекватно самому протоколу ethernet.

А вот дальше все это оборачивается в recv, и как мне кажется, совершенно зря.

Точнее, сама то функция может и не так уж плоха, но вот возможности повесить коллбэк на приход пакета явно не хватает

 

cvs-255 ()

Сокеты, браузер, write. Что здесь происходит?! [решено]

Есть сервер. Работает на локалхосте. Он создал слушающий сокет. Получив что-то на вход, он записывает в ответ msg. Клиент msg получает и отображает. Вот код:

char *msg = "HTTP/1.1 200 OK\n\n\n<h1>This is site</h1>";
/*...*/
read(socket_accept, buf, SIZE);
/*...*/
fprintf(stdout, "This is stdout\n");
write(socket_accept, msg, strlen(msg));
fprintf(stderr, "It's stderr\n");

Всё работает.

Но стоит увеличить третий параметр в write, например так:

write(socket_accept, msg, strlen(msg)+100);

Происходит интересное. Если клиент консольный - вроде бы всё нормально. Однако, если обратиться через браузер (127.0.0.1:port), то на страницу выдачи сначала попадает содержимое msg, затем результаты двух fprintf (начиная с первого), затем N одинаковых нераспознаваемых символов (примерно 100 минус длина результатов fprintf).

Что здесь происходит и почему?

 , , , ,

Edward_I ()

Можно ли запихнуть данные назад в сокет если слишком много прочитал recv?

сабж.

Мне кажется что я где-то что-то такое читал, но может это было и не про сокеты. Поясни, дорогой ЛОР

// сокеты обычные, сетевые, линуксовые

 

pihter ()

Python работа с сокетами (RFID считыватель)

Привет.

Подскажите пожалуйста как автоматизировать вот такой кейс:

  1. У меня есть устройство (rfid считыватель) которое подключено к модему.
  2. И на мой vds поступают id карт которые считывает это устройство (rfid считыватель)
  3. Я слушая 500 порт на сервере вижу такие сообщения (nc -nvlp 500) :

A000000001 A000000001 A000000002

Они идут постоянно потоком один айди за другим (каждый с новой строки)

Я хочу автоматизировать это все - чтобы реализовать примерно такую логику:

Сделаю БД, занесу айдишники в базу данных и для некоторых разрешу вход а для некоторых нет.

Пока будет достаточно вывода в консоль сообщений : Ок и НЕТ

Как я понял мне нужно работать с сокетами. Вот нашел, поправил два скрипта: server.py http://paste.org.ru/?rlsg79 client.py http://paste.org.ru/?5hvlgq

Но они не видят похоже что приходит на 500 порт - потому что не отдают айдишники на клиент обратно. Сейчас скрипты видят что подключились к сокету и все. Может быть нужно как-то пробросить порт или что то такое?

Подскажите пожалуйста как реализовать данный механизм?

 , ,

feltramt ()

Мой прокси сервер слишком медленный

Ребята, возникла задача написать прокси сервер под линуксы на сишке. Вот я написал и сервак очень сильно лагает, тупит и не может загрузить ютуб видео банально. Ребята, помогите, я не знаю почему он такой медленный, я вроде все по потокам разбил (на каждый поток по 64 сокета) и юзаю асинхронные сокеты для poll'инга

Буду благодарен если вы хотя-бы просто посмотрите и подскажите что мне переделать

Вот исходник https://pastebin.com/yMSNJcCz

 , , , ,

MikkotoNikki ()

Почему в linux, bsd и прочих unix у сокетов api не соответствует напрямую протоколам?

Например

sock = socket(AF_INET, SOCK_STREAM, 0);

Тут нигде не написано, что это именно TCP. Мы можем это понять, почитав документацию

Аналогично

sock = socket(AF_INET, SOCK_DGRAM, 0);

не говорит о том, что это надо использовать UDP.

А если я захочу использовать SCPT, то надо будет делать

socket (AF_INET, SOCK_STREAM, IPPROTO_SCTP);

Немного неочевидно, чем принципиально TCP отличается от SCTP, что для TCP не надо указывать явно протокол, а для SCTP надо.

В общем, какая-то странная система, в которой вместо того, чтобы явно указывать, какой протокол использовать, зачем-то используется довольная неуклюжая попытка абстрагирования.

Почему нельзя было сделать проще и именовать протоколы по именам, которые указаны в описывающих их RFC, а не выдумывать какие-то ненужные абстракции?

Вроде такого:

socket(AF_INET, SOCK_TCP);
socket(AF_INET, SOCK_UDP);
socket(AF_INET, SOCK_SCTP);
socket(AF_INET, SOCK_RAW);

 ,

cvs-255 ()

php сокеты почему один код медленнее в 6 раз чем другой?

отправляю строку:

   
fwrite($fp, $cfg_message, strlen($cfg_message));

Вариант 1:

    while (($t = fgets ($fp, 1024)) !== false) {
        if(strpos($t,'\r\n') == false)
            $tempbuffer .= $t;        
    }
    echo $tempbuffer;

Вариант 2:

    $tempbuffer = fgets($fp, 1024);
    echo $tempbuffer;

Вариант 2 работает примерно за 1 секунду.

Вариант 1 работает примерно за 60 секунд, такое ощущение что по таймауту.

 , ,

sniper21 ()

В поисках Процессора

Доброго времени суток! Мне нужна помощь в кратчайшие сроки. Мне дали задачу на «сборку компьютера» Но не много в старой форме, ищу для материнской платы процессор с сокетом AMD F(s1207) с поддержкой ecc. Если хоть у кого то есть информация желательно ссылка на магазин или какой-то другой источник по процессору. Буду очень признателен.

 , ,

XYDOJNIKO ()

Создание сетевых приложений в среде linux. Шон Уолтон 2001

Нашел, на полке, данную книгу. Но сильно смущает год. Есть ли смысл читать такую старую литературу. Читать для «общего развития» много времени нету.
Сильно ли, что либо поменялось, в данной сфере, в linux?

 ,

tema696 ()

Ожидание при создании сокета

На 2.6.32-5-openvz-amd64 виртуалке (UBC в норме) давно работают apache 2.2.15, perl, fcgi. После увеличения количества клиентов стал непредсказуемо долго отвечать апач. Хотя порт perl/fcgi процесса открывается быстро. Апач может ответить сразу, а может и десяток секунд поджождать.

Вот что сообщает tcpdump на «telnet server 80»:

13:24:08.832202 IP CLIENT_ADDR.48284 > SERVER_ADDR.http: Flags [S], seq 3463188871, win 29200, options [mss 1460,sackOK,TS val 18688018 ecr 0,nop,wscale 7], length 0
13:24:10.836416 IP CLIENT_ADDR.48284 > SERVER_ADDR.http: Flags [S], seq 3463188871, win 29200, options [mss 1460,sackOK,TS val 18688519 ecr 0,nop,wscale 7], length 0
13:24:14.840816 IP CLIENT_ADDR.48284 > SERVER_ADDR.http: Flags [S], seq 3463188871, win 29200, options [mss 1460,sackOK,TS val 18689520 ecr 0,nop,wscale 7], length 0
13:24:22.857613 IP CLIENT_ADDR.48284 > SERVER_ADDR.http: Flags [S], seq 3463188871, win 29200, options [mss 1460,sackOK,TS val 18691524 ecr 0,nop,wscale 7], length 0
13:24:38.906990 IP CLIENT_ADDR.48284 > SERVER_ADDR.http: Flags [S], seq 3463188871, win 29200, options [mss 1460,sackOK,TS val 18695536 ecr 0,nop,wscale 7], length 0
13:24:38.907002 IP SERVER_ADDR.http > CLIENT_ADDR.48284: Flags [S.], seq 187742972, ack 3463188872, win 5792, options [mss 1460,sackOK,TS val 185966 ecr 18695536,nop,wscale 7], length 0
13:24:38.959519 IP CLIENT_ADDR.48284 > SERVER_ADDR.http: Flags [.], ack 1, win 229, options [nop,nop,TS val 18695549 ecr 185966], length 0
$netstat -ant| wc -l
7457

httpd server-status: 81.1 requests/sec - 12.4 kB/second - 156 B/request 82 requests currently being processed, 20 idle workers

Куда копать?

 , ,

magnio ()

Несколько вопросов по Qt и его QTcpServer

1. Дали задание сделать клиент и сервер на Qt, задание сделал и после его отправки, мне ответили, что использование QTcpServer нежелательно, а как делать иначе не знаю (предполагаю, через QTcpSocket), впервые использую Qt для чего либо, поэтому делал по примерам, найденным в сети, а там везде QTcpServer, почему так, если это плохо?

2. Также в задании предполагалась обработка нескольких соединений одновременно, у меня же получается только одно, более того, при подключенном клиенте, если подключится ещё один, начинается какая то вакханалия с передачей данных - второму подключению вместо слова для поиска передаётся часть текста из файла первого, после чего второй переходит в ожидание, пока первый не освободится. В самом начале, когда делал по примеру, предполагал, что такая реализация сервера будет обрабатывать сразу несколько соединений, но оказалось не так, хотел добавить форки, но не стал, подумал это будет не совсем правильно, а правильным будет добавить потоки (QThread), так ли это? Если да, то как это лучше сделать, чтобы не исправлять всё полностью? Если нет, то какой подход лучше использовать?

3. В клиентском clientwindow.cpp в конструкторе я попытался задать регулярные выражения, чтобы word_for_searching не давал вводить недопустимые символы, только буквы и цифры, но, опять-таки, то как это описано в примерах, не сработало, приложение сразу закрывается, хотя всё логично и компилятор не выдаёт предупреждений и ошибок. Что не так?

4. В clientwindow.cpp есть функция loading, её задача показывать анимацию загрузки на экране загрузки из-за неё всё повисает при подключении или анимация вовсе не работает, я подозреваю это тоже нужно делать через потоки?

5. Нужно подсчитать количество слов в файле - когда я передаю файл от клиента серверу есть возможность на сервере сразу вести подсчёт, миную фазу записи в файл, а потом его открытие, считывание и закрытие. Так вот с этим 2 вопроса:

5.1 Если переводить QByteArray в строку, также надо будет париться о том, чтобы очередное слово было полным и уже потом считать, а иначе дочитывать из сокета дополнительные данные, это не будет дольше или займёт такое же количество времени, как если бы я работал с файлом, к тому же из файла можно читать пословно до пробела?

5.2 Как сделать проверку очередного полученного QByteArray на принадлежность к отдельному слову? И как считывая из файла игнорировать спецсимволы? А то, допустим, в тексте «Улыбок тебе, дед макар.» «тебе,» и «макар.» будут интерпретированы, как слова, а если будут пропущены пробелы после точек и запятых, это вообще получится одно большое слово. Я хотел добавить закрытую функцию, которая бы проверяла очередное слово на отсутствие символов точек, запятых и т.д., но вдруг есть более простое решение экономящее время.

https://gitlab.com/iamclock/Qt-question

 , , , ,

clock ()

tcp-сокет пересылает данные на разные адреса без переподключения

в общем есть примерно такой код:

int fd = socket(); <<----получили файловый дескриптор
/**/
connect(); <<----тут приконнектились к одному адресу, у меня это 127.0.0.1:1200
send();    <<----отправили что-то

fd = socket(); <<-----тут записали в fd уже другой дескриптор
/**/
connect(); <<-----тут приконнектились к другому адресу, теперь уже 127.0.0.1:1220 

send();    <<-----отправили что-то
ошибок то вроде возвращаяемых нет, но вопрос: нормально ли все сделано, или нужно было после первого send сделать close() сокета?

 , ,

xperious ()

Расскажите в деталях как пользоваться неблокирующими сокетами

Собственно, сабж. Хочу повысить собственный навык network programming до уровня, достаточно для написания веб сервера, принимающего множество подключений.

Что удалось понять самостоятельно:

  1. Использование блокирующих сокетов и запись/чтение через классические read()/write() в потоке для каждого подключения имеет смысл только если сервер не рассчитан на большое кол-во подключения (ибо большое кол-во потоков будет жрать память) в пользу простоты кода.
  2. Использование неблокирующих сокетов имеет смысл если нужно принимать много подключений, и данных оттуда могут поступать не сразу/медленно/с задержкой. Посему можно набрать пачку подключений и потом poll()-ить их.
  3. Создание потока (posix threads) или процесса (fork()) - довольно затратная операция, и потому для отзывчивого и/или производительного сервера есть смысл создавать потоки/процессы заранее, а потом передавать им дескрипторы.
  4. Использование блокирующих вызовов ввода-вывода (т.е. write() и read()) не позволяет добиться информации о ошибках типа «потеря соединения» или «network is unreachable», и потому приходится использовать неблокирующие сокеты и соответствующие вызовы.

Что не удалось понять и требуются пояснения:

  1. Как передать дескриптор уже существующему потоку? Я так понял, что никаких спец. техник не нужно, поток просто должен знать номер и всё.
  2. Для передачи дескриптора уже существующему процессу (который создали при помощи fork()) нужно что-то шаманить с sendmsg(). Дальше я не копал. Судя по всему, этим не особо активно пользуются в современном софте, хотя хз. К слову, я так и не понял чем именно sendmsg() заставляет получить дескриптор в процессе, а не просто передаёт информацию.
  3. Если send() и другие функции из той же семьи возвращают кол-во переданных/полученных байт, то как они могут что-то вернуть, если они сразу возвращают управление? Что они возвращают в таком случае?
  4. Можно ли использовать буфер сразу после того, как send() вернул управление? Если да, то он, получается, сначала копирует буфер в пространство ядра, а потом возвращает управление (т.е. send() всё-таки не мгновенно возвращает, лол). Если нет, то когда можно снова использовать буфер? Нужно poll()-ить и ждать пока poll() вернёт результат по соответствующему дескриптору?
  5. Если poll()-ить менее пары десятков дескрипторов, можно ли забить болт на epoll() или kqueue()?
  6. Есть ли какой-то годный туториал (от простого к сложному, можно и на английском), который бы посвятил бы во всякие тонкости типа тех, которые будут в следующем пункте:
  7. Если poll() сообщает, что есть входящие данные по дескриптору, но чтение их возвращает 0, означает ли это, что удалённый хост просто сделал close()?
  8. Зачем нужен shutdown(), если есть обычный close()?

 , ,

IECTA ()

не биндится сокет к 80 порту

здравствуйте, есть си-шный код:

int sockfd, newsockfd, portno;
             socklen_t clilen;
             char buffer[256];
             struct sockaddr_in serv_addr, cli_addr;
             int n;
             sockfd = socket(AF_INET, SOCK_STREAM, 0);
             bzero((char *) &serv_addr, sizeof(serv_addr));
             portno = atoi("80");
             serv_addr.sin_family = AF_INET;
             serv_addr.sin_addr.s_addr = INADDR_ANY;
             serv_addr.sin_port = htons(portno);
             if (bind(sockfd, (struct sockaddr *) &serv_addr,
                      sizeof(serv_addr)) < 0) {}
             listen(sockfd,5);
             clilen = sizeof(cli_addr);
             newsockfd = accept(sockfd,
                         (struct sockaddr *) &cli_addr,
                         &clilen);
             if (newsockfd < 0) {}
                  printf("ERROR on accept");
             bzero(buffer,256);
             n = read(newsockfd,buffer,255);
             if (n < 0) printf("ERROR reading from socket");
             printf("Here is the message: %s\n",buffer);
             n = write(newsockfd,"I got your message",18);
             if (n < 0) printf("ERROR writing to socket");
             close(newsockfd);
             close(sockfd);
запускаю, делаю netstat -tulpn:
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:51927           0.0.0.0:*               LISTEN      15914/some_simple   
udp        0      0 0.0.0.0:68              0.0.0.0:*                           2589/dhcpcd         
udp        0      0 0.0.0.0:5353            0.0.0.0:*                           3156/libpepflashpla 
udp6       0      0 :::5353                 :::*                                3156/libpepflashpla 
сокет не прибиндился к 80 порту, а прослушивает черти какой, в чем ошибка?

 , ,

xperious ()

Можно ли 2 (или 3) раза сделать запись в асинхронный сокет, не дождавшись пред. вызовов?

Т.е. мы 3 раза в асинхр. сокет сделаем write. Так можно делать? Никакой ошибки не будет? А TCP данные не перепутаются у нас в этом случае?

 , ,

facelift ()

Сокеты в C.

Здравствуйте! Мне нужно написать функцию отправки сокетов на сервер. На python 3 эта функция была easy. Но недавно решил освоить C. И пробовал гуглить. Но ничего интересного не нашел. Кто знает как написать эту функцию плиз скиньте код.

 ,

levon12341 ()

Вопрос про systemd, сокеты и проблему с программным прослушиванием трафика для отказа от сокетов.

Решил я автоматизировать процесс запуска dnscrypt-proxy с помощью systemd, ибо надоело после каждой перезагрузки запускать из консоли. Погуглил — нашел готовый шаблон — сделал. Вроде бы можно насладиться успехом — но нет, мне захотелось разобраться что это за конфиги и что они делают. Все шло успешно, пока я не споткнулся об одну теоретически решаемую проблему, при желании заменить целый конфиг на пару символов.

dnscrypt-proxy — софт, цель которого в шифровании DNS трафика и его обменом со специальными DNS серверами.
dnscrypt-proxy имеет функцию прослушивания трафика с помощью атрибута -a [ip:port]

Итак, имеется есть два юнита: сокет dnscrypt-proxy.socket, который слушает IP 127.0.0.2:53(DNS трафик, в моем случае) и перенаправляет весь трафик на служебный юнит dnscrypt-proxy.service, который уже работает непосредственно с dnscrypt-proxy, если я правильно разобрался.

Так вот, сам вопрос: почему команда dnscrypt-proxy -R dns.server.name -a 127.0.0.2:53 не равна записи ExecStart=/usr/sbin/dnscrypt-proxy -R dns.server.name -a 127.0.0.2:53 в конфиге? Иначе как объяснить, что первая работает, а вторая — нет?


__________
Вот как выглядят юниты:
-----
/etc/systemd/system/dnscrypt-proxy.service

[Unit]
Description=DNSCrypt client proxy
Requires=dnscrypt-proxy.socket

[Install]
WantedBy=multi-user.target

[Service]
Type=simple
NonBlocking=true
ExecStart=/usr/sbin/dnscrypt-proxy -R dns.server.name

-----
/etc/systemd/system/dnscrypt-proxy.socket
[Unit]
Description=dnscrypt-proxy listening socket
After=network.target

[Socket]
ListenStream=127.0.0.2:53
ListenDatagram=127.0.0.2:53

[Install]
WantedBy=sockets.target
__________

 ,

letni ()