Пример #1
0
// Open Ethernet adapter (Pcap)
ETH *OpenEthPcap(char *name, bool local, bool tapmode, char *tapaddr)
{
	char errbuf[PCAP_ERRBUF_SIZE];
	ETH *e;
	pcap_t *p;
	CANCEL *c;

	// Validate arguments
	if (name == NULL || tapmode != false)
	{
		return NULL;
	}
	
	// Initialize error message buffer
	errbuf[0] = 0;

	// Open capturing device
	p = pcap_open_live(name, 65535, (local == false), 1, errbuf);
	if(p==NULL)
	{
		return NULL;
	}

	// Set to non-block mode
	// (In old BSD OSs, 'select(2)' don't block normally for BPF device. To prevent busy loop)
	/*
	if(pcap_setnonblock(p, true, errbuf) == -1)
	{
		Debug("pcap_setnonblock:%s\n",errbuf);
		pcap_close(p);
		return NULL;
	}
	*/
	
	e = ZeroMalloc(sizeof(ETH));
	e->Name = CopyStr(name);
	e->Title = CopyStr(name);
	e->Queue = NewQueue();
	e->QueueSize = 0;
	e->Cancel = NewCancel();
	e->IfIndex = -1;
	e->Socket = pcap_get_selectable_fd(p);
	e->Pcap = p;
	
	e->CaptureThread = NewThread(PcapThread, e);
	WaitThreadInit(e->CaptureThread);

	return e;
}
Пример #2
0
extern	SessionCtrl*
NewSessionCtrl(
	SessionCtrlType type)
{
	SessionCtrl *ctrl;
	
	ctrl = g_new0(SessionCtrl,1);
	ctrl->type = type;
	ctrl->waitq = NewQueue();
	ctrl->sysdbval = RecParseValueMem(SYSDBVAL_DEF,NULL);
	InitializeValue(ctrl->sysdbval);
	ctrl->sysdbvals = RecParseValueMem(SYSDBVALS_DEF,NULL);

	InitializeValue(ctrl->sysdbvals);
	return ctrl;
}
Пример #3
0
static bool _WorkerInit(ThreadData _worker) {
    Worker* worker = (Worker*)_worker;
    if ((worker->queue = NewQueue()) == NULL) {
        return false;
    }

    if ((worker->pool = NewBufferPool(worker->bufferSize)) == NULL) {
        return false;
    }

    if ((worker->writer = NewWriter(worker->pipe, worker->bufferSize)) == NULL) {
        return false;
    }

    Log(AIO4C_LOG_LEVEL_DEBUG, "initialized with tid 0x%08lx", ThreadGetId(worker->thread));

    return true;
}
Пример #4
0
static bool _ReaderInit(ThreadData _reader) {
    Reader* reader = (Reader*)_reader;
    if ((reader->selector = NewSelector()) == NULL) {
        return false;
    }

    if ((reader->queue = NewQueue()) == NULL) {
        return false;
    }

    if ((reader->worker = NewWorker(reader->pipe, reader->bufferSize)) == NULL) {
        return false;
    }

    Log(AIO4C_LOG_LEVEL_DEBUG, "initialized with tid 0x%08lx", ThreadGetId(reader->thread));

    return true;
}
Пример #5
0
Server* NewServer(AddressType type, char* host, aio4c_port_t port, int bufferSize, int nbPipes, void (*handler)(Event,Connection*,void*), void* handlerArg, void* (*dataFactory)(Connection*,void*)) {
    Server* server = NULL;
    ErrorCode code = AIO4C_ERROR_CODE_INITIALIZER;

    if ((server = aio4c_malloc(sizeof(Server))) == NULL) {
#ifndef AIO4C_WIN32
        code.error = errno;
#else /* AIO4C_WIN32 */
        code.source = AIO4C_ERRNO_SOURCE_SYS;
#endif /* AIO4C_WIN32 */
        code.size = sizeof(Server);
        code.type = "Server";
        Raise(AIO4C_LOG_LEVEL_ERROR, AIO4C_ALLOC_ERROR_TYPE, AIO4C_ALLOC_ERROR, &code);
        return NULL;
    }

    server->address    = NewAddress(type, host, port);
    server->pool       = NewBufferPool(bufferSize);
    server->factory    = NewConnectionFactory(server->pool, dataFactory, handlerArg);
    server->acceptor   = NULL;
    server->thread     = NULL;
    server->handler    = handler;
    server->queue      = NewQueue();
    server->nbPipes    = nbPipes;
    server->thread     = NewThread(
            "server",
            _serverInit,
            _serverRun,
            _serverExit,
            (ThreadData)server);

    if (server->thread == NULL) {
        FreeAddress(&server->address);
        FreeBufferPool(&server->pool);
        FreeConnection(&server->factory);
        FreeQueue(&server->queue);
        aio4c_free(server);
        return NULL;
    }

    return server;
}
Пример #6
0
int main(void) {
	puts("!!!Hello World!!!"); /* prints !!!Hello World!!! */
	Queue* q = NewQueue(5);
	q->enqueue(q, 2);
	q->enqueue(q, 3);
	q->enqueue(q, 4);
	q->enqueue(q, 5);
	q->enqueue(q, 6);
	q->dequeue(q);
	q->dequeue(q);
	q->enqueue(q, 7);
	q->enqueue(q, 8);
	q->dequeue(q);
	q->enqueue(q, 9);
	for (int i = 0; i < q->size; i++){
		printf("%d,", q->dequeue(q));
	}
	printf("\nQueue Free: %d", q->free);
	return EXIT_SUCCESS;
}
Пример #7
0
// Initialize the packet adapter
bool LinkPaInit(SESSION *s)
{
	LINK *k;
	THREAD *t;
	// Validate arguments
	if (s == NULL || (k = (LINK *)s->PacketAdapter->Param) == NULL)
	{
		return false;
	}

	// Create a transmission packet queue
	k->SendPacketQueue = NewQueue();

	// Creat a link server thread
	t = NewThread(LinkServerSessionThread, (void *)k);
	WaitThreadInit(t);

	ReleaseThread(t);

	return true;
}
Пример #8
0
// パケットアダプタ初期化
bool LinkPaInit(SESSION *s)
{
	LINK *k;
	THREAD *t;
	// 引数チェック
	if (s == NULL || (k = (LINK *)s->PacketAdapter->Param) == NULL)
	{
		return false;
	}

	// 送信パケットキューの作成
	k->SendPacketQueue = NewQueue();

	// リンクサーバースレッドの作成
	t = NewThread(LinkServerSessionThread, (void *)k);
	WaitThreadInit(t);

	ReleaseThread(t);

	return true;
}
Пример #9
0
// Initialize the packet adapter
bool NullPaInit(SESSION *s)
{
	NULL_LAN *n;
	// Validate arguments
	if (s == NULL)
	{
		return false;
	}

	n = ZeroMalloc(sizeof(NULL_LAN));
	s->PacketAdapter->Param = (void *)n;

	n->Cancel = NewCancel();
	n->PacketQueue = NewQueue();
	n->Event = NewEvent();

	GenMacAddress(n->MacAddr);

	n->PacketGeneratorThread = NewThread(NullPacketGenerateThread, n);

	return true;
}
Пример #10
0
extern	int
ConnectTerm(
	int		_fhTerm)
{
	int				fhTerm;
	pthread_t		thr;
	pthread_attr_t	attr;
	TermNode		*term;

ENTER_FUNC;
	pthread_attr_init(&attr);
	pthread_attr_setstacksize(&attr,256*1024);
	if ((fhTerm = accept(_fhTerm,0,0)) < 0) {
		Error("accept(2) failure:%s",strerror(errno));
	}
	term = New(TermNode);
	term->que = NewQueue();
	term->fp = SocketToNet(fhTerm);
	pthread_create(&thr,&attr,(void *(*)(void *))TermThread,(void *)term);
	pthread_detach(thr);
LEAVE_FUNC;
	return	(fhTerm); 
}
Пример #11
0
// Start tracking of the routing table
void RouteTrackingStart(SESSION *s)
{
	VLAN *v;
	ROUTE_TRACKING *t;
	UINT if_id = 0;
	ROUTE_ENTRY *e;
	ROUTE_ENTRY *dns = NULL;
	ROUTE_ENTRY *route_to_real_server_global = NULL;
	char tmp[64];
	UINT exclude_if_id = 0;
	bool already_exists = false;
	bool already_exists_by_other_account = false;
	IP eight;
	// Validate arguments
	if (s == NULL)
	{
		return;
	}

	v = (VLAN *)s->PacketAdapter->Param;
	if (v->RouteState != NULL)
	{
		return;
	}

	// Get the interface ID of the virtual LAN card
	if_id = GetInstanceId(v->InstanceName);
	Debug("[InstanceId of %s] = 0x%x\n", v->InstanceName, if_id);

	if (MsIsVista())
	{
		// The routing table by the virtual LAN card body should be
		// excluded explicitly in Windows Vista
		exclude_if_id = if_id;
	}

	// Get the route to the server
	e = GetBestRouteEntryEx(&s->ServerIP, exclude_if_id);
	if (e == NULL)
	{
		// Acquisition failure
		Debug("Failed to get GetBestRouteEntry().\n");
		return;
	}
	IPToStr(tmp, sizeof(tmp), &e->GatewayIP);
	Debug("GetBestRouteEntry() Succeed. [Gateway: %s]\n", tmp);

	// Add a route
	if (MsIsVista())
	{
		e->Metric = e->OldIfMetric;
	}
	if (AddRouteEntryEx(e, &already_exists) == false)
	{
		FreeRouteEntry(e);
		e = NULL;
	}
	Debug("already_exists: %u\n", already_exists);

	if (already_exists)
	{
		if (s->Cedar->Client != NULL && s->Account != NULL)
		{
			UINT i;
			ACCOUNT *a;
			for (i = 0;i < LIST_NUM(s->Cedar->Client->AccountList);i++)
			{
				a = LIST_DATA(s->Cedar->Client->AccountList, i);
				Lock(a->lock);
				{
					SESSION *sess = a->ClientSession;
					if (sess != NULL && sess != s)
					{
						VLAN *v = sess->PacketAdapter->Param;
						if (v != NULL)
						{
							ROUTE_TRACKING *tr = v->RouteState;
							if (tr != NULL && e != NULL)
							{
								if (Cmp(tr->RouteToServer, e, sizeof(ROUTE_ENTRY)) == 0)
								{
									already_exists_by_other_account = true;
								}
							}
						}
					}
				}
				Unlock(a->lock);
			}
		}

		if (already_exists_by_other_account)
		{
			Debug("already_exists_by_other_account = %u\n", already_exists_by_other_account);
			already_exists = false;
		}
	}

	// Get the routing table to the DNS server
	// (If the DNS server is this PC itself, there's no need to get)
	if (IsZeroIP(&s->DefaultDns) == false)
	{
		if (IsMyIPAddress(&s->DefaultDns) == false)
		{
			dns = GetBestRouteEntryEx(&s->DefaultDns, exclude_if_id);
			if (dns == NULL)
			{
				// Getting failure
				Debug("Failed to get GetBestRouteEntry DNS.\n");
			}
			else
			{
				// Add a route
				if (MsIsVista())
				{
					dns->Metric = dns->OldIfMetric;

					if (AddRouteEntry(dns) == false)
					{
						FreeRouteEntry(dns);
						dns = NULL;
					}
				}
			}
		}
	}

	if (s->IsAzureSession && IsZeroIP(&s->AzureRealServerGlobalIp) == false)
	{
		// Add also a static route to the real server in the case of via VPN Azure
		if (IsMyIPAddress(&s->AzureRealServerGlobalIp) == false)
		{
			route_to_real_server_global = GetBestRouteEntryEx(&s->AzureRealServerGlobalIp, exclude_if_id);

			if (route_to_real_server_global != NULL)
			{
				if (MsIsVista())
				{
					route_to_real_server_global->Metric = route_to_real_server_global->OldIfMetric;
				}

				if (AddRouteEntry(route_to_real_server_global) == false)
				{
					FreeRouteEntry(route_to_real_server_global);
					route_to_real_server_global = NULL;
				}
			}
		}
	}

	// Initialize
	if (s->Cedar->Client != NULL && s->Account != NULL)
	{
		Lock(s->Account->lock);
	}

	t = ZeroMalloc(sizeof(ROUTE_TRACKING));
	v->RouteState = t;

	t->RouteToServerAlreadyExists = already_exists;
	t->RouteToServer = e;
	t->RouteToDefaultDns = dns;
	t->RouteToRealServerGlobal = route_to_real_server_global;
	t->VLanInterfaceId = if_id;
	t->NextTrackingTime = 0;
	t->DeletedDefaultGateway = NewQueue();
	t->OldDefaultGatewayMetric = 0x7fffffff;

	if (s->Cedar->Client != NULL && s->Account != NULL)
	{
		Unlock(s->Account->lock);
	}

	// Get the route to 8.8.8.8
	SetIP(&eight, 8, 8, 8, 8);
	t->RouteToEight = GetBestRouteEntryEx(&eight, exclude_if_id);

	// Get the current default DNS server to detect network changes
	GetDefaultDns(&t->OldDnsServer);

	// Get as soon as releasing the IP address in the case of using DHCP
	if (IsNt())
	{
		char tmp[MAX_SIZE];
		MS_ADAPTER *a;

		Format(tmp, sizeof(tmp), VLAN_ADAPTER_NAME_TAG, v->InstanceName);
		a = MsGetAdapter(tmp);

		if (a != NULL)
		{
			if (a->UseDhcp)
			{
				bool ret = Win32ReleaseAddressByGuidEx(a->Guid, 100);
				Debug("*** Win32ReleaseAddressByGuidEx = %u\n", ret);

				ret = Win32RenewAddressByGuidEx(a->Guid, 100);
				Debug("*** Win32RenewAddressByGuidEx = %u\n", ret);
			}

			MsFreeAdapter(a);
		}
	}
	else
	{
		// For Win9x
		Win32RenewDhcp9x(if_id);
	}

	// Clear the DNS cache
	Win32FlushDnsCache();

	// Detect a change in the routing table (for only supported OS)
	t->RouteChange = NewRouteChange();
	Debug("t->RouteChange = 0x%p\n", t->RouteChange);
}
Пример #12
0
// Open Ethernet adapter (BPF)
ETH *OpenEthBpf(char *name, bool local, bool tapmode, char *tapaddr)
{
	ETH *e;
	CANCEL *c;
	char devname[MAX_SIZE];
	int n = 0;
	int fd;
	int ret;
	UINT bufsize;
	struct ifreq ifr;
	struct timeval to;
	
	// Find unused bpf device and open it
	do{
		Format(devname, sizeof(devname), "/dev/bpf%d", n++);
		fd = open (devname, O_RDWR);
		if(fd<0){
			perror("open");
		}
	}while(fd < 0 && errno == EBUSY);
	
	// No free bpf device was found
	if(fd < 0){
		Debug("BPF: No minor number are free.\n");
		return NULL;
	}
	
	// Enlarge buffer size
	n = 524288; // Somehow(In libpcap, this size is 32768)
	while(true){
		// Specify buffer size
		ioctl(fd, BIOCSBLEN, &n);

		// Bind to the network device
		StrCpy(ifr.ifr_name, IFNAMSIZ, name);
		ret = ioctl(fd, BIOCSETIF, &ifr);
		if(ret < 0){
			if(ret == ENOBUFS && n>1500){
				// Inappropriate buffer size
				// Retry with half buffer size
				// If buffer size is under 1500 bytes, something goes wrong
				n /= 2;
				continue;
			}
			Debug("bpf: binding network failed.\n");
			close(fd);
			return NULL;
		}else{
			break;
		}
	}
	bufsize = n;

	// Set to promiscuous mode
	if(local == false){
		if (ioctl(fd, BIOCPROMISC, NULL) < 0){
			printf("bpf: promisc mode failed.\n");
			close(fd);
			return NULL;
		}
	}

	
	// Set to immediate mode (Return immediately when packet arrives)
	n = 1;
	if (ioctl(fd, BIOCIMMEDIATE, &n) < 0){
		Debug("BPF: non-block mode failed.\n");
		close(fd);
		return NULL;
	}

	// Set receiving self sending packet
	n = 1;
	if (ioctl(fd, BIOCGSEESENT, &n) < 0){
		Debug("BPF: see sent mode failed.\n");
		close(fd);
		return NULL;
	}

	// Header complete mode (Generate whole header of sending packet)
	n = 1;
	if (ioctl(fd, BIOCSHDRCMPLT, &n) < 0){
		Debug("BPF: Header complete mode failed.\n");
		close(fd);
		return NULL;
	}
	
	// Set timeout delay to 1 second
	to.tv_sec = 1;
	to.tv_usec = 0;
	if (ioctl(fd, BIOCSRTIMEOUT, &to) < 0){
		Debug("BPF: Read timeout setting failed.\n");
		close(fd);
		return NULL;
	}
	
	e = ZeroMalloc(sizeof(ETH));
	e->Name = CopyStr(name);
	e->Title = CopyStr(name);
	e->IfIndex = -1;
	e->Socket = fd;
	e->BufSize = bufsize;

#ifdef BRIDGE_BPF_THREAD
	e->Queue = NewQueue();
	e->QueueSize = 0;
	e->Cancel = NewCancel();

	// Start capture thread
	e->CaptureThread = NewThread(BpfThread, e);
	WaitThreadInit(e->CaptureThread);

#else // BRIDGE_BPF_THREAD
	c = NewCancel();
	UnixDeletePipe(c->pipe_read, c->pipe_write);
	c->pipe_read = c->pipe_write = -1;
	c->SpecialFlag = true;
	c->pipe_read = fd;
	e->Cancel = c;
	e->Buffer = Malloc(bufsize);
	e->Next = e->Buffer;
	e->Rest = 0;

	// Set to non-blocking mode
	UnixSetSocketNonBlockingMode(fd, true);
#endif // BRIDGE_BPF_THREAD

	// Open interface control socket for FreeBSD
	e->SocketBsdIf = socket(AF_LOCAL, SOCK_DGRAM, 0);

	// Get MTU value
	e->InitialMtu = EthGetMtu(e);

	return e;
}
Пример #13
0
ETH *OpenEthInternal(char *name, bool local, bool tapmode, char *tapaddr)
{
	WP_ADAPTER *t;
	ETH *e;
	ADAPTER *a = NULL;
	HANDLE h;
	CANCEL *c;
	MS_ADAPTER *ms;
	char name_with_id[MAX_SIZE];
	SU *su = NULL;
	SU_ADAPTER *su_adapter = NULL;
	// Validate arguments
	if (name == NULL || IsEthSupported() == false)
	{
		return NULL;
	}

	if (tapmode)
	{
		// Tap is not supported in Windows
		return NULL;
	}

	Lock(eth_list_lock);

	InitEthAdaptersList();

	t = Win32EthSearch(name);

	if (t == NULL)
	{
		Unlock(eth_list_lock);
		return NULL;
	}

	Debug("OpenEthInternal: %s\n", t->Name);

	if (StartWith(t->Name, SL_ADAPTER_ID_PREFIX))
	{
		// Open with SU
		su = SuInit();
		if (su == NULL)
		{
			// Fail to initialize SU
			Unlock(eth_list_lock);
			return NULL;
		}

		su_adapter = SuOpenAdapter(su, t->Name);

		if (su_adapter == NULL)
		{
			// Fail to get adapter
			SuFree(su);
			Unlock(eth_list_lock);
			return NULL;
		}

		is_using_selow = true;
	}
	else
	{
		// Open with SEE
		a = wp->PacketOpenAdapter(t->Name);
		if (a == NULL)
		{
			Unlock(eth_list_lock);
			return NULL;
		}

		if (IsWin32BridgeWithSee() == false)
		{
			MsSetThreadSingleCpu();
		}

		is_using_selow = false;
	}

	e = ZeroMalloc(sizeof(ETH));
	e->Name = CopyStr(t->Name);

	Win32EthMakeCombinedName(name_with_id, sizeof(name_with_id), t->Title, t->Guid);
	e->Title = CopyStr(name_with_id);

	if (su_adapter != NULL)
	{
		// SU
		e->SuAdapter = su_adapter;
		e->Su = su;

		// Get event object
		h = e->SuAdapter->hEvent;

		c = NewCancelSpecial(h);
		e->Cancel = c;
	}
	else
	{
		// SEE
		e->Adapter = a;

		wp->PacketSetBuff(e->Adapter, BRIDGE_WIN32_ETH_BUFFER);
		wp->PacketSetHwFilter(e->Adapter, local ? 0x0080 : 0x0020);
		wp->PacketSetMode(e->Adapter, PACKET_MODE_CAPT);
		wp->PacketSetReadTimeout(e->Adapter, -1);
		wp->PacketSetNumWrites(e->Adapter, 1);

		if (wp->PacketSetLoopbackBehavior != NULL)
		{
			// Filter loopback packet in kernel
			if (GET_KETA(GetOsType(), 100) >= 3)
			{
				if (MsIsWindows8() == false)
				{
					// Enable for Windows XP, Server 2003 or later
					// But disable for Windows 8 or later
					bool ret = wp->PacketSetLoopbackBehavior(e->Adapter, 1);
					Debug("*** PacketSetLoopbackBehavior: %u\n", ret);

					e->LoopbackBlock = ret;
				}
			}
		}

		// Get event object
		h = wp->PacketGetReadEvent(e->Adapter);

		c = NewCancelSpecial(h);
		e->Cancel = c;

		e->Packet = wp->PacketAllocatePacket();

		e->PutPacket = wp->PacketAllocatePacket();
	}

	e->Buffer = Malloc(BRIDGE_WIN32_ETH_BUFFER);
	e->BufferSize = BRIDGE_WIN32_ETH_BUFFER;

	e->PacketQueue = NewQueue();

	// Get MAC address by GUID
	ms = MsGetAdapterByGuid(t->Guid);
	if (ms != NULL)
	{
		if (ms->AddressSize == 6)
		{
			Copy(e->MacAddress, ms->Address, 6);
		}

		MsFreeAdapter(ms);
	}

	Unlock(eth_list_lock);

	return e;
}
Пример #14
0
// アダプタを開く (BPF)
ETH *OpenEthBpf(char *name, bool local, bool tapmode, char *tapaddr)
{
	ETH *e;
	CANCEL *c;
	char devname[MAX_SIZE];
	int n = 0;
	int fd;
	int ret;
	UINT bufsize;
	struct ifreq ifr;
	struct timeval to;
	
	// 未使用の bpf デバイスを探して開く
	do{
		Format(devname, sizeof(devname), "/dev/bpf%d", n++);
		fd = open (devname, O_RDWR);
		if(fd<0){
			perror("open");
		}
	}while(fd < 0 && errno == EBUSY);
	
	// 開くことが出来るbpfデバイスが無ければエラー
	if(fd < 0){
		Debug("BPF: No minor number are free.\n");
		return NULL;
	}
	
	// バッファサイズを拡大
	n = 524288; // なんとなく(libpcapでは32768だった)
	while(true){
		// バッファサイズを指定
		ioctl(fd, BIOCSBLEN, &n);

		// ネットワークをバインド
		StrCpy(ifr.ifr_name, IFNAMSIZ, name);
		ret = ioctl(fd, BIOCSETIF, &ifr);
		if(ret < 0){
			if(ret == ENOBUFS && n>1500){
				// バッファサイズが不適切
				// サイズを半分にしてリトライ
				// バッファサイズ1500バイト以下でエラーになるのは何かおかしい
				n /= 2;
				continue;
			}
			Debug("bpf: binding network failed.\n");
			close(fd);
			return NULL;
		}else{
			break;
		}
	}
	bufsize = n;

	// プロミスキャスモードに設定
	if(local == false){
		if (ioctl(fd, BIOCPROMISC, NULL) < 0){
			printf("bpf: promisc mode failed.\n");
			close(fd);
			return NULL;
		}
	}

	
	// 即時モードに設定(パケットを受信するとタイムアウトを待たず、すぐにreadがreturnする)
	n = 1;
	if (ioctl(fd, BIOCIMMEDIATE, &n) < 0){
		Debug("BPF: non-block mode failed.\n");
		close(fd);
		return NULL;
	}

	// 自分が送信するパケットも受信する
	n = 1;
	if (ioctl(fd, BIOCGSEESENT, &n) < 0){
		Debug("BPF: see sent mode failed.\n");
		close(fd);
		return NULL;
	}


	// ヘッダ完全モード(送信するパケットのヘッダも自分で生成する)
	n = 1;
	if (ioctl(fd, BIOCSHDRCMPLT, &n) < 0){
		Debug("BPF: Header complete mode failed.\n");
		close(fd);
		return NULL;
	}
	
	// read のタイムアウト時間を設定(1秒)
	to.tv_sec = 1;
	to.tv_usec = 0;
	if (ioctl(fd, BIOCSRTIMEOUT, &to) < 0){
		Debug("BPF: Read timeout setting failed.\n");
		close(fd);
		return NULL;
	}
	
	e = ZeroMalloc(sizeof(ETH));
	e->Name = CopyStr(name);
	e->Title = CopyStr(name);
	e->IfIndex = -1;
	e->Socket = fd;
	e->BufSize = bufsize;

#ifdef BRIDGE_BPF_THREAD
	e->Queue = NewQueue();
	e->QueueSize = 0;
	e->Cancel = NewCancel();

	// キャプチャ用スレッドの開始
	e->CaptureThread = NewThread(BpfThread, e);
	WaitThreadInit(e->CaptureThread);

#else // BRIDGE_BPF_THREAD
	c = NewCancel();
	UnixDeletePipe(c->pipe_read, c->pipe_write);
	c->pipe_read = c->pipe_write = -1;
	c->SpecialFlag = true;
	c->pipe_read = fd;
	e->Cancel = c;
	e->Buffer = Malloc(bufsize);
	e->Next = e->Buffer;
	e->Rest = 0;

	// ノンブロッキングモードに設定
	UnixSetSocketNonBlockingMode(fd, true);
#endif // BRIDGE_BPF_THREAD

	// FreeBSD 用インターフェイス操作用ソケットを作成
	e->SocketBsdIf = socket(AF_LOCAL, SOCK_DGRAM, 0);

	// MTU の取得
	e->InitialMtu = EthGetMtu(e);

	return e;
}
Пример #15
0
int main(int argc, char * argv[]) {
	if (argc != 4) {
		fprintf(stderr, "Usage : %s <input file> <input chunking metafile> <instanceID>\n", argv[0]);
		return 0;
	}
	uint64_t i;

	int ifd = open(argv[1], O_RDONLY);
	int ofd = open(argv[2], O_RDONLY);
	assert(ifd != -1);
	assert(ofd != -1);

	posix_fadvise(ofd, 0, 0, POSIX_FADV_WILLNEED);
	uint64_t isize = lseek(ifd, 0, SEEK_END);
	uint64_t osize = lseek(ofd, 0, SEEK_END);
	uint64_t entries = osize / sizeof(Segment);
	uint8_t * data = MMAP_FD_RO(ifd, isize);
	Segment * base_seg = MMAP_FD_PV(ofd, osize);

	printf("Number of Segments: %d\n",entries);

	mmq = LongQueue();
	void * cdata = MMAP_MM(MAX_SEG_SIZE * LONGQUEUE_LENGTH);
	for (i = 0; i < LONGQUEUE_LENGTH; i++) {
		Enqueue(mmq, cdata + i * MAX_SEG_SIZE);
	}

	IndexService * is = GetIndexService();
	ImageService * es = GetImageService();
	CompressService * cs = GetCompressService();
	BucketService * bs = GetBucketService();


	Queue * miq = NewQueue();
	Queue * icq = NewQueue();
	Queue * ceq = NewQueue();
	Queue * ebq = NewQueue();
	Queue * bmq = NewQueue();

	is->start(miq, icq);
	cs->start(icq, ceq);
	es->start(ceq, ebq, atoi(argv[3]));
	bs->start(ebq, bmq);
	pthread_t mid;
	pthread_create(&mid, NULL, end, bmq);

	struct timeval x;
	TIMERSTART(x);

	for (i = 0; i < entries; i++) {
		Segment * seg = base_seg + i;
		seg->data = data + seg->offset;
		seg->cdata = Dequeue(mmq);
		Enqueue(miq, seg);
	}
	Enqueue(miq, NULL);

	pthread_join(mid, NULL);
	TIMERSTOP(x);
	printf("%ld.%06ld\n", x.tv_sec, x.tv_usec);

	is->stop();
	cs->stop();
	es->stop();
	bs->stop();

	free(miq);
	free(icq);
	free(ceq);
	free(ebq);
	free(bmq);

	munmap(data, isize);
	munmap(base_seg, osize);
	munmap(cdata, MAX_SEG_SIZE * LONGQUEUE_LENGTH);
	free(mmq);
	close(ifd);
	close(ofd);

	return 0;
}
Пример #16
0
// Create a new UDP acceleration function
UDP_ACCEL *NewUdpAccel(CEDAR *cedar, IP *ip, bool client_mode, bool random_port, bool no_nat_t)
{
	UDP_ACCEL *a;
	SOCK *s;
	UINT max_udp_size;
	bool is_in_cedar_port_list = false;

	if (IsZeroIP(ip))
	{
		ip = NULL;
	}

	if (client_mode || random_port)
	{
		// Use a appropriate vacant port number in the case of using random port or client mode
		s = NewUDPEx3(0, ip);
	}
	else
	{
		// Specify in the range in the case of server mode
		UINT i;
		s = NULL;

		LockList(cedar->UdpPortList);
		{
			for (i = UDP_SERVER_PORT_LOWER;i <= UDP_SERVER_PORT_HIGHER;i++)
			{
				if (IsIntInList(cedar->UdpPortList, i) == false)
				{
					s = NewUDPEx3(i, ip);

					if (s != NULL)
					{
						is_in_cedar_port_list = true;
						break;
					}
				}
			}

			if (s == NULL)
			{
				// Leave the port selection to the OS because the available port is not found within the range
				s = NewUDPEx3(0, ip);
			}

			if (s != NULL && is_in_cedar_port_list)
			{
				AddIntDistinct(cedar->UdpPortList, i);
			}
		}
		UnlockList(cedar->UdpPortList);
	}

	if (s == NULL)
	{
		return NULL;
	}

	a = ZeroMalloc(sizeof(UDP_ACCEL));

	a->Cedar = cedar;
	AddRef(a->Cedar->ref);

	a->NoNatT = no_nat_t;


	a->NatT_TranId = Rand64();

	a->CreatedTick = Tick64();

	a->IsInCedarPortList = is_in_cedar_port_list;

	a->ClientMode = client_mode;

	a->Now = Tick64();
	a->UdpSock = s;
	Rand(a->MyKey, sizeof(a->MyKey));
	Rand(a->YourKey, sizeof(a->YourKey));

	Copy(&a->MyIp, ip, sizeof(IP));
	a->MyPort = s->LocalPort;

	a->IsIPv6 = IsIP6(ip);

	if (a->IsIPv6)
	{
		a->NoNatT = true;
	}

	a->RecvBlockQueue = NewQueue();

	Rand(a->NextIv, sizeof(a->NextIv));

	do
	{
		a->MyCookie = Rand32();
	}
	while (a->MyCookie == 0);

	do
	{
		a->YourCookie = Rand32();
	}
	while (a->MyCookie == 0 || a->MyCookie == a->YourCookie);

	// Calculate the maximum transmittable UDP packet size
	max_udp_size = MTU_FOR_PPPOE;

	if (a->IsIPv6 == false)
	{
		// IPv4
		max_udp_size -= 20;
	}
	else
	{
		// IPv6
		max_udp_size -= 40;
	}

	// UDP
	max_udp_size -= 8;

	a->MaxUdpPacketSize = max_udp_size;

	Debug("Udp Accel My Port = %u\n", a->MyPort);

	// Initialize the NAT-T server IP address acquisition thread
	a->NatT_Lock = NewLock();
	a->NatT_HaltEvent = NewEvent();

	if (a->NoNatT == false)
	{
		a->NatT_GetIpThread = NewThread(NatT_GetIpThread, a);
	}

	return a;
}