LINUX.ORG.RU

Сообщения KIR_PRO

 

mreamap() режет указатель до 32-битного

Форум — Development

Приветствую. Накидал такой код:

		void* fileMem, *pos;
		int fd, res;
		long int flen, fpos;
		size_t i,o,p;
	fd = open( "myfile.txt", O_RDONLY );
	if( fd < 0 )
		exit(1);
	flen = lseek64( fd, 0, SEEK_END );
	if( -1 == flen ){
		perror("llseek(): ");
		exit(1);
	}
	lseek64( fd, 0, SEEK_SET );

	fileMem = mmap( 0, pageLimit, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0 );
	if( fileMem == MAP_FAILED ){
		perror("llseek(): ");
		exit(1);
	}
	memset( fileMem, 'a', pageLimit );
	//fileMem = mremap(fileMem, pageLimit, pageLimit*2, 1 );  //Incorrect pointer
	fileMem = syscall(SYS_mremap, fileMem, pageLimit, pageLimit*2, 1 );  //Correct pointer
	if( fileMem == MAP_FAILED ){
		switch(errno){
			case ENOMEM:
				printf("NO memory\n");
				break;
			case EINVAL:
				printf("Invalid args\n");
				break;
		}
		perror("mremap(): ");
		exit(1);
	}

	memset( fileMem + pageLimit, 'b', pageLimit );
	write( 1, fileMem, pageLimit*2 );
И столкнулся с проблемой, библиотечная mremap() возвращает не 64-х битный указатель, а 32-х битный, что естественно влечет за собой SIGSEGV. Однако вызов mremap посредством syscall() возвращает корректный 64-х битный указатель. Кто подскажет как лечить? Можно конечно остановиться на использовании syscall(), но хочется разобраться чем вызвано такое поведение. strace показывает что системный вызов возвращает к примеру 0x7ff97af82000, а SIGSEGV происходит при обращении к адресу 0x7af83000. Следовательно именно mreamap вернула урезанное значение.

p.s. компилятор ругается на оба способа вызова mremap() так: "warning: assignment makes pointer from integer without a cast" p.p.s. список всех заголовков в коде:

#define _LARGEFILE64_SOURCE
#include <stdio.h> //printf
	#include <linux/sched.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/time.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
	#include <limits.h>
#include <errno.h>
#include <error.h>
#include <signal.h>
	#include <sys/mman.h>
#include <resolv.h>
#include <netdb.h>
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>

 , ,

KIR_PRO
()

need HELP: VPN с доступом через разное сервеное ПО ( OpenVPN + (PPTPD or (xl2tpd + IPsec) ) + Radius )

Форум — Admin

Приветствую всех. Имеется готовая сеть:

Имеем следующее:

Есть виртуальная сеть поднятая посредством OpenVPN. Сеть состоит из 5 серверов: S1: WIP=1.1.1.1 Головной сервер, на котором стоит MySQL + Freeradius S2: WIP=2.2.2.2 Рядовой сервер как и оставшиеся три, к ним подключаются клиенты. На борту OpenVPN(tcp + udp) S3: WIP=3.3.3.3 S4: WIP=4.4.4.4 S5: WIP=5.5.5.5 *WIP - внешний IP сервера

На S1 запущен OpenVPN сервер, к которому подключаются все остальные сервера, подсеть 10.127.0.0/24 назовем её ServiceNet, сам сервер соответственно имеет IP=10.127.0.1, а остальные в соответствии со своим номером: (S2)IP=10.127.0.2; (S3)IP=10.127.0.3; (S4)IP=10.127.0.4; (S5)IP=10.127.0.5 Эта сеть сделана специально для управления серверами, а именно для работы серверов с Radius, сбора информации, и управления подключениями клиентов(а точнее их отключения).

Интерфейсы для ServiceNET на серверах: S1=tun0 S2=tun0 S3=tun0 S4=tun0 S5=tun0

Для сервера S1 это все,на нем более никаких интерфейсов не будет. На серверах S2-S5 идет одинаковое распределение интерфейсов под конкретные цели:

  • tun1 - OpenVpn сервер по протоколу tcp
  • tun2 - OpenVpn сервер по протоколу udp
  • tun3 - reserved
  • tun4 - reserved

Но у каждого сервера для клиентов своя подсеть:

  • S2:
    • tun1 - 10.128.2.0/25
    • tun2 - 10.128.2.127/25
  • S3:
    • tun1 - 10.128.3.0/25
    • tun2 - 10.128.3.127/25
  • S4:
    • tun1 - 10.128.4.0/25
    • tun2 - 10.128.4.127/25
  • S5:
    • tun1 - 10.128.5.0/25
    • tun2 - 10.128.5.127/25

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

Корневые сертификаты и клиентский(он один для всех) на всех серверах едины, потому клиент может сам выбирать к какому подключиться, т.к. авторизация идет по Логину/паролю. Radius успешно сверяет данные и создает сессию, а OpenVpn стабильно и послушно отдает данные аккаунтинга Radius серверу, а тот пишет их в базу.

Идем далее... Каждый сервер соединен с другим по типу «звездочка» (или кому понятнее: «каждый к каждому»), назовем эту сеть RouteNet, т.к. это название наиболее полно отражает её предназначение =). Не буду описывать логику по которой определяется какой сервер к какому подключается, опишу лишь то что считаю нужным. Соединяются они с помощью OpenVPN типа p2p, что позволяет избавиться от накладных расходов по трафику и авторизации. На каждое такое соединение каждый сервер запускает свою копию OpenVPN (клиент/сервер) с отдельным интерфейсом и отдельными (не пересекающимися адресами). При соединении серверов Sx и Sy, серверу Sx будет присвоен IP=10.127.y.x а серверу Sy будет присвоен IP=10.127.x.y. Тогда при соединении S2 и S3 серверов они получат следующие IP:

  • S2(IP)=10.127.3.2
  • S3(IP)=10.127.2.3

Тем самым когда вся RouteNet соединиться, получаем удобное распределение адресов для маршрутизации. К примеру чтобы с S2 перенаправить трафик клиента на сервер S4 достаточно будет направить его на IP 10.127.2.4, соответственно для направления на S3 или S5, отправляем на адреса 10.127.2.3 и 10.127.2.5.

Поначалу может показаться сложным, но эту схему главно понять =) Теперь когда пользователь подключается к сети, специально написанная прога берет из базы маршрут для него и прописывает на необходимые сервера. Опишу как это происходит.

на каждом сервере есть таблица в iproute2 следующего содержания:

ip ru list 0: from all lookup local 32762: from all fwmark 0x5 lookup to_srv5 32763: from all fwmark 0x4 lookup to_srv4 32764: from all fwmark 0x3 lookup to_srv3 32765: from all fwmark 0x2 lookup to_srv2 32766: from all lookup main 32767: from all lookup default

В которой конечно нету правила для самого себя (т.е. на сервере S2 не будет строки from all fwmark 0x2 lookup to_srv2).

ну и для каждой таблицы (to_srv2/to_srv3/etc..) прописан маршрут по умолчанию:

#ip ro ist table to_srv3 default via 10.127.2.3 dev tun7

это все настраивается единожды, при помощи самописного скрипта или ручками, не суть важно.

Теперь лишь остается помечать пакеты, для отправки, пакеты не помеченные шлются в соответствии с адресом назначения по правилам ip ro list А теперь пояснительный пример:

Клиент user1 подключился к S2 и для него, в базе, записан маршрут S2-S5-S3. Что означает, что его трафик будет перенаправляться с S2 на S5, а с S5 на S3 и только потом выходить к адресу назначения. Обратный путь трафика точно такой же. После подключения на S2 добавляется правило:

iptables -t mangle -A PREROUTING -s 10.128.2.2/32 -j MARK --set-mark 5

на S5 добавляется два правила:

iptables -t mangle -A PREROUTING -s 10.128.2.2/32 -j MARK --set-mark 3 iptables -t mangle -A PREROUTING -d 10.128.2.2/32 -j MARK --set-mark 2

на S3 добавляется одно хитрое правило которое пришлось чуть чуть поискать:

iptables -t mangle -A PREROUTING -i eth0 -m conntrack --ctstate SNAT --ctorigsrc 10.128.2.2 -j MARK --set-mark 5

и трафик успешно гуляет от клиента и к клиенту.

таким образом добавляя динамические маршруты, мы гибко рулим трафиком и эффективно используем сеть. Не хватает лишь того из-за чего, я и обратился к вам.

Встала задача, чтоб клиенты могли пользоваться не только OpenVPN, а еще и стандартными средствами в Win/Mac/nix и мобильных устройствах. Я пока что вижу перспективу только у PPTPd или xl2tpd+ipsec, больше ничего не нашел, что может взаимодействовать с этими клиентскими платформами без установки доп.ПО. Больше волнует следующее:

  • на PPTPD для каждого клиента создается PPPx интерфейс, интересует во первых лимит этих интерфейсов, и что если у меня при этом будет 200 созданных tunX интерфейсов?
  • возможно ли как то заставить PPTPD не создавать новые интерфейсы, а работать со всеми клиентами на одном PPP0 интерфейсе или и того лучше юзать /dev/tun (в мане на pppd есть конфиг ttyname не поможет?)
  • Плагин radius работает ли с сессиями и шлет данные аккаунтинга?
  • Как можно отключить клиента от сервера НЕ грубыми методами типа iptables -s x.x.x.x -j REJECT/DROP ?

Пока что не удалось успешно настроить (xl2tpd/l2tpd)+ipsec а тем более подцепить к нему авторизацию Radius, но интересует следующее:

  • Имеется ли возможность создания одного интерфейса pppX для всех клиентов, или же как PPTPD будет создаваться на каждого клиента свой интерфейс pppX?
  • Имеется ли возможность Radius сессиий и аккаунтинга?
  • Как отключать клиентов не грубыми методами?

И конечно же выслушаю ваши предложения ПО которое поддерживается клиентскими платформами стандартно и может быть интегрировано в вышеописанную сеть.

 , , ,

KIR_PRO
()

RSS подписка на новые темы