Example #1
0
/*
 ****************************************************************
 *	Devolve um UDP EP para a lista livre			*
 ****************************************************************
 */
void
put_udp_ep (register UDP_EP *up)
{
	register ITSCB	*ip = &itscb;
	register UDP_EP *aup;

#ifdef	MSG
	if (up == NO_UDP_EP)
	    { printf ("%g: Devolvendo EP NULO\n"); return; }
#endif	MSG

	up->up_state = -1;

	/*
	 *	Em primeiro lugar, tira da fila "busy"
	 */
	SPINLOCK (&ip->it_uep_lock);

	if (ip->it_uep_busy == up)
	{
		ip->it_uep_busy = up->up_next;
	}
	else for (aup = ip->it_uep_busy; /* abaixo */; aup = aup->up_next)
	{
		if (aup == NO_UDP_EP)
		{
			SPINFREE (&ip->it_uep_lock);
#ifdef	MSG
			printf ("%g: Não achei o EP na fila BUSY\n");
#endif	MSG
			return;
		}

		if (aup->up_next == up)
		{
			aup->up_next = up->up_next;
			break;
		}
	}

	SPINFREE (&ip->it_uep_lock);

	/*
	 *	Remove as filas
	 */
	delete_udp_queues (up);

	/*
	 *	Devolve o EP para a lista livre
	 */
	SPINLOCK (&ip->it_uep_lock);

	up->up_next = ip->it_uep_free;
	ip->it_uep_free = up;

	ip->it_uep_count--;

	SPINFREE (&ip->it_uep_lock);

}	/* end put_udp_ep */
Example #2
0
/*
 ****************************************************************
 *	Obtém um UDP EP da lista livre				*
 ****************************************************************
 */
UDP_EP	*
get_udp_ep (void)
{
	register ITSCB	*ip = &itscb;
	register UDP_EP	*up;

	SPINLOCK (&ip->it_uep_lock);

	if ((up = ip->it_uep_free) == NO_UDP_EP)
		{ SPINFREE (&ip->it_uep_lock); return (NO_UDP_EP); }

	ip->it_uep_free = up->up_next;

	memclr (up, sizeof (UDP_EP));

	up->up_next = ip->it_uep_busy;
	ip->it_uep_busy = up;

	ip->it_uep_count++;

	SPINFREE (&ip->it_uep_lock);

	return (up);

}	/* end get_udp_ep */
Example #3
0
/*
 ****************************************************************
 *	Obtém um RAW EP da lista livre				*
 ****************************************************************
 */
RAW_EP	*
get_raw_ep (void)
{
	register ITSCB	*ip = &itscb;
	register RAW_EP	*rp;

	SPINLOCK (&ip->it_rep_lock);

	if ((rp = ip->it_rep_free) == NO_RAW_EP)
		{ SPINFREE (&ip->it_rep_lock); return (NO_RAW_EP); }

	ip->it_rep_free = rp->rp_next;

	memclr (rp, sizeof (RAW_EP));

	rp->rp_next = ip->it_rep_busy;
	ip->it_rep_busy = rp;

	ip->it_rep_count++;

	SPINFREE (&ip->it_rep_lock);

	return (rp);

}	/* end get_raw_ep */
Example #4
0
/*
 ****************************************************************
 *	Obtém um TCP EP da lista livre				*
 ****************************************************************
 */
TCP_EP	*
get_tcp_ep (void)
{
	register ITSCB	*ip = &itscb;
	register TCP_EP	*tp;

	SPINLOCK (&ip->it_tep_lock);

	if ((tp = ip->it_tep_free) == NO_TCP_EP)
		{ SPINFREE (&ip->it_tep_lock); return (NO_TCP_EP); }

	ip->it_tep_free = tp->tp_next;

	memclr (tp, sizeof (TCP_EP));

	tp->tp_next = ip->it_tep_busy;
	ip->it_tep_busy = tp;

	ip->it_tep_count++;

	SPINFREE (&ip->it_tep_lock);

	return (tp);

}	/* end get_tcp_ep */
Example #5
0
/*
 ****************************************************************
 *	Libera as filas de um UDP EP				*
 ****************************************************************
 */
void
delete_udp_queues (register UDP_EP *up)
{
	register ITBLOCK *bp;
	register int	i;
	ITBLOCK	 	*it_forw;

	/*
	 *	Devolve os blocos da fila de entrada
	 */
   	SPINLOCK (&up->up_inq_lock);

	bp = up->up_inq_first;
	up->up_inq_first = NOITBLOCK;

	EVENTCLEAR (&up->up_inq_nempty);

   	SPINFREE (&up->up_inq_lock);

	for (i = 0; bp != NOITBLOCK; bp = it_forw)
		{ it_forw = bp->it_inq_forw.inq_ptr; put_it_block (bp); i++; }

#ifdef	MSG
	if (i > 0 && itscb.it_report_error)
		printf ("%g: %d bloco(s) residual(is) na entrada\n", i);
#endif	MSG

}	/* end delete_udp_queues */
Example #6
0
EXPORT_C_(void) PADWriteEvent(keyEvent &evt)
{
    // This function call be called before PADopen. Therefore we cann't
    // guarantee that the spin lock was initialized
    if (mutex_WasInit) {
        SPINLOCK(&mutex_KeyEvent);
        ev_fifo.push(evt);
        SPINUNLOCK(&mutex_KeyEvent);
    }
}
Example #7
0
/*
 ****************************************************************
 *	Verifica se o destino é o próprio computador		*
 ****************************************************************
 */
void
check_for_pipe_mode (TCP_EP *tp)
{
	ITSCB		*ip = &itscb;
	TCP_EP		*dst_tp;

	/*
	 *	Se o modo não foi pedido, nada faz
	 */
	if (!ip->it_pipe_mode)
		return;

	if (tp->tp_dst_addr != MY_IP_ADDR)
		return;

	/*
	 *	Examina os "endpoints"
	 */
	SPINLOCK (&ip->it_tep_lock);

	for (dst_tp = ip->it_tep_busy; /* abaixo */; dst_tp = dst_tp->tp_next)
	{
		if (dst_tp == NO_TCP_EP)
			{ SPINFREE (&ip->it_tep_lock); return; }

		if (dst_tp->tp_my_addr != MY_IP_ADDR)
			continue;

		if (dst_tp->tp_my_port == tp->tp_dst_port)
			break;

	}	/* end procurando o EP correspondente ao "port" */

	/*
	 *	Altera o modo
	 */
	tp->tp_pipe_tcp_ep = dst_tp; 
	tp->tp_pipe_mode   = 1; 

	dst_tp->tp_pipe_tcp_ep = tp; 
	dst_tp->tp_pipe_mode   = 1; 

	SPINFREE (&ip->it_tep_lock);

	EVENTDONE (&tp->tp_pipe_event);
	EVENTWAIT (&dst_tp->tp_pipe_event, PITNETIN);

} 	/* end check_for_pipe_mode */
Example #8
0
void PollForKeyboardInput(int pad)
{
    keyEvent evt;

    // Keyboard input send by PCSX2
    while (!ev_fifo.empty()) {
        SPINLOCK(&mutex_KeyEvent);

        evt = ev_fifo.front();
        // First platform specific functionality. End if handled.
        if (PlatformAnalyzeKeyEvent(evt))
            AnalyzeKeyEvent(pad, evt);
        ev_fifo.pop();

        SPINUNLOCK(&mutex_KeyEvent);
    }

    // keyboard input
#if 0 // TODO OSX similar logic for OSX, check keyboard input from NSAPI or WX or SDL
    while (XPending(GSdsp) > 0)
    {
        XNextEvent(GSdsp, &E);

        // Change the format of the structure to be compatible with GSOpen2
        // mode (event come from pcsx2 not X)
        evt.evt = E.type;
        switch (E.type) {
            case MotionNotify:
                evt.key = (E.xbutton.x & 0xFFFF) | (E.xbutton.y << 16);
                break;
            case ButtonRelease:
            case ButtonPress:
                evt.key = E.xbutton.button;
                break;
            default:
                evt.key = (int)XLookupKeysym(&E.xkey, 0);
        }

        AnalyzeKeyEvent(pad, evt);
    }
#endif
}
Example #9
0
void 
vmm_aspace(PROCESS *actprp, PROCESS **pactprp) {
	ADDRESS					*adp;

	if((adp = actprp->memory)) {
		InterruptDisable();
		SPINLOCK(&asid_spin);
		if(adp->cpu.asid > VM_ASID_BOUNDARY) {
			// later move it out for minimize int disable time
			alloc_asid(adp); 
		}
		SPINUNLOCK(&asid_spin);
		smp_tlb_sync(actprp);

		// Set the ASID
		out32(SH_MMR_CCN_PTEH, 
				(in32(SH_MMR_CCN_PTEH) & ~VM_ASID_MASK)  | adp->cpu.asid);
		// Set the page table
		out32(SH_MMR_CCN_TTB, (uintptr_t)adp->cpu.pgdir);
		*pactprp = actprp;

		InterruptEnable();
	}
}
Example #10
0
/*
 ****************************************************************
 *	Associa um "port" a um "endpoint"			*
 ****************************************************************
 */
void
k_bind (int minor, const T_BIND *req, T_BIND *ret)
{
	ITSCB		*ip = &itscb;
	KFILE		*fp = u.u_fileptr;
	T_BIND		bind;
	INADDR		addr[2];	/* Local, remoto */
	int		port_given = 0, negotiate_qlen = 0;
	static long	udp_port_source = MIN_UDP_PORT;
	static long	tcp_port_source = MIN_TCP_PORT;

	/*
	 *	Analisa o endereço dado
	 */
	addr[1].a_addr = 0;	addr[1].a_port = 0;	/* Remoto */

	if (req != (T_BIND *)NULL)
	{
		if (unimove (&bind, req, sizeof (T_BIND), US) < 0)
			{ u.u_error = EFAULT; return; }

		if (bind.qlen < 0)
			bind.qlen = 0;
	}
	else
	{
		bind.addr.len = 0;
		bind.qlen = 0;
	}

	if (bind.addr.len != 0)
	{
		if (bind.addr.len != sizeof (INADDR) && bind.addr.len != 2 * sizeof (INADDR))
			{ u.u_error = TBADADDR; return; }

		if (unimove (&addr[0], bind.addr.buf, bind.addr.len, US) < 0)
			{ u.u_error = EFAULT; return; }

		if (addr[0].a_port != 0)
			port_given++;

		if (addr[1].a_addr == 0 && addr[1].a_port != 0)
			{ u.u_error = TBADADDR; return; }
	}

	/*
	 *	Verifica qual o protocolo a utilizar
	 */
	switch (minor)
	{
		/*
		 *	Protocolo RAW
		 */
	    case RAW:
	    {
		RAW_EP		*rp;

		if (fp->f_union != KF_ITNET)
			{ u.u_error = EBADF; return; }

		rp = fp->f_endpoint;

		SLEEPLOCK (&rp->rp_lock, PITNETOUT);

		if (rp->rp_state != S_UNBOUND)
			{ SLEEPFREE (&rp->rp_lock); u.u_error = TOUTSTATE; return; }

		rp->rp_bind_proto = addr[0].a_proto;
		rp->rp_bind_addr  = addr[0].a_addr;

		rp->rp_state	= S_BOUND;

		SLEEPFREE (&rp->rp_lock);

		break;
	    }

		/*
		 *	Protocolo UDP
		 */
	    case UDP:
	    {
		UDP_EP		*up;

		SPINLOCK (&ip->it_uep_lock);

		if (!port_given)
		{
		    udp_again:
			if (udp_port_source > MAX_UDP_PORT)
				udp_port_source = MIN_UDP_PORT;

			addr[0].a_port = udp_port_source++;
		}
		else switch (addr[0].a_port)
		{
		    case PMAP_PORT:
		    case RPC_PORT:
		    case NFS_CLIENT_PORT:
			SPINFREE (&ip->it_uep_lock);
			u.u_error = TADDRBUSY;
			return;
		}

		/*
		 *	Verifica se este "port" já está sendo utilizado
		 */
		for (up = ip->it_uep_busy; up != NO_UDP_EP; up = up->up_next)
		{
			if (up->up_my_port != addr[0].a_port)
				continue;

			if (!port_given)
				goto udp_again;

			SPINFREE (&ip->it_uep_lock);
			u.u_error = TADDRBUSY;
			return;
		}

		SPINFREE (&ip->it_uep_lock);

		/*
		 *	Associa o "port" ao "endpoint"
		 */
		if (fp->f_union != KF_ITNET)
			{ u.u_error = EBADF; return; }

		up = fp->f_endpoint;

		SLEEPLOCK (&up->up_lock, PITNETOUT);

		if (up->up_state != S_UNBOUND)
			{ SLEEPFREE (&up->up_lock); u.u_error = TOUTSTATE; return; }

		up->up_my_port   = addr[0].a_port;

		up->up_bind_addr = addr[1].a_addr;
		up->up_bind_port = addr[1].a_port;

		up->up_state	 = S_BOUND;

		SLEEPFREE (&up->up_lock);

		break;
	    }

		/*
		 *	Protocolo TCP
		 */
	    case TCP:
	    {
		TCP_EP		*tp;

		SPINLOCK (&ip->it_tep_lock);

		if (!port_given)
		{
		    tcp_again:
			if (tcp_port_source > MAX_TCP_PORT)
				tcp_port_source = MIN_TCP_PORT;

			addr[0].a_port = tcp_port_source++;
		}

		/*
		 *	Verifica se este "port" já está sendo utilizado
		 */
		for (tp = ip->it_tep_busy; tp != NO_TCP_EP; tp = tp->tp_next)
		{
			if (tp->tp_my_port != addr[0].a_port)
				continue;

			if (!port_given)
				goto tcp_again;

			if (bind.qlen > 0 && tp->tp_listen_maxqlen > 0)
				goto busy;

			if (tp->tp_dst_addr != addr[1].a_addr)
			{
				if (addr[1].a_addr != 0)
					continue;
			}

			if (tp->tp_dst_port != addr[1].a_port)
			{
				if (addr[1].a_port != 0)
					continue;
			}

		    busy:
			SPINFREE (&ip->it_tep_lock);
			u.u_error = TADDRBUSY;
			return;
		}

		SPINFREE (&ip->it_tep_lock);

		/*
		 *	Associa o "port" ao "endpoint"
		 */
		if (fp->f_union != KF_ITNET)
			{ u.u_error = EBADF; return; }

		tp = fp->f_endpoint;

		SLEEPLOCK (&tp->tp_lock, PITNETOUT);

		if (tp->tp_state != S_UNBOUND)
			{ SLEEPFREE (&tp->tp_lock); u.u_error = TOUTSTATE; return; }

	   /***	SPINLOCK (&tp->tp_inq_lock); ***/

		negotiate_qlen = MIN (bind.qlen, LISTENQ_MAXSZ);

		tp->tp_listen_maxqlen = negotiate_qlen;
		tp->tp_listen_qlen    = 0;
		tp->tp_listen_source  = 0;
		memclr (tp->tp_listen_q, sizeof (tp->tp_listen_q));

	   /***	SPINFREE (&tp->tp_inq_lock); ***/

		tp->tp_my_port	= addr[0].a_port;

		tp->tp_dst_addr	= addr[1].a_addr;
		tp->tp_dst_port	= addr[1].a_port;

		tp->tp_state	= S_BOUND;

		sort_tcp_ep (tp);

		SLEEPFREE (&tp->tp_lock);

		break;
	    }

		/*
		 *	Protocolos INEXISTENTES
		 */
	    default:
		u.u_error = ENXIO;
		return;

	}	/* end switch */

	/*
	 *	Copia as estrutura T_BIND e INADDR de volta
	 */
	if (ret != (T_BIND *)NULL)
	{
		if (unimove (&bind, ret, sizeof (T_BIND), US) < 0)
			{ u.u_error = EFAULT; return; }

		if (bind.addr.maxlen < sizeof (INADDR))
			{ u.u_error = TBUFOVFLW; return; }

		bind.addr.len = bind.addr.maxlen;

		if (bind.addr.len > 2 * sizeof (INADDR))
			bind.addr.len = 2 * sizeof (INADDR);

		addr[0].a_addr = 0;	addr[0].a_family = 0;

		if (unimove (bind.addr.buf, &addr[0], bind.addr.len, SU) < 0)
			{ u.u_error = EFAULT; return; }

		if (minor == TCP)
			bind.qlen = negotiate_qlen;

		if (unimove (ret, &bind, sizeof (T_BIND), SU) < 0)
			{ u.u_error = EFAULT; return; }
	}

}	/* end k_bind */
Example #11
0
/*
 ****************************************************************
 *	Espera por um pedido de conexão				*
 ****************************************************************
 */
void
k_listen (T_CALL *callp)
{
	KFILE		*fp = u.u_fileptr;
	TCP_EP		*tp;
	LISTENQ		*lp;
	const LISTENQ	*end_listen_q;
	T_CALL		call;
	INADDR		addr;

	/*
	 *	Copia a estrutura "call" do usuário
	 */
	if (fp->f_union != KF_ITNET)
		{ u.u_error = EBADF; return; }

	tp = fp->f_endpoint;

	if (unimove (&call, callp, sizeof (T_CALL), US) < 0)
		{ u.u_error = EFAULT; return; }

	if (call.addr.maxlen < sizeof (INADDR))
		{ u.u_error = TBUFOVFLW; return; }

	/*
	 *	Verifica o estado do "endpoint"
	 */
	if (tp->tp_state == S_BOUND)
		tp->tp_state = S_LISTEN;

	if (tp->tp_state != S_LISTEN)
		{ u.u_error = TOUTSTATE; return; }

	if (tp->tp_listen_maxqlen <= 0)
		{ u.u_error = TBADQLEN; return; }

	/*
	 *	Espera chegar um pedido de conexão (um SYN)
	 */
	for (EVER)
	{
		if (tp->tp_rst)
			{ u.u_error = TLOOK; return; }

		SPINLOCK (&tp->tp_inq_lock);

		for (lp = tp->tp_listen_q, end_listen_q = lp + LISTENQ_MAXSZ; lp < end_listen_q; lp++)
		{
			if (lp->tp_listen_seq > 0)
				goto found;

		}	/* end for (lista de listen) */

		EVENTCLEAR (&tp->tp_inq_nempty);

		SPINFREE (&tp->tp_inq_lock);

		if (u.u_oflag & O_NDELAY)
			{ u.u_error = TNODATA; return; }

		EVENTWAIT (&tp->tp_inq_nempty, PITNETIN);

	}	/* end for (EVER) */

	/*
	 *	O servidor recebe o endereço do cliente e o no. de seqüência
	 */
    found:
	addr.a_addr = lp->tp_listen_addr;
	addr.a_port = lp->tp_listen_port;

	call.addr.len	= sizeof (INADDR);
	call.sequence	= lp->tp_listen_seq;

	lp->tp_listen_seq = -lp->tp_listen_seq;		/* "t_listen" já forneceu */

	SPINFREE (&tp->tp_inq_lock);

	call.opt.len	= 0;
	call.udata.len	= 0;

	if (unimove (call.addr.buf, &addr, sizeof (INADDR), SU) < 0)
		{ u.u_error = EFAULT; return; }

	if (unimove (callp, &call, sizeof (T_CALL), SU) < 0)
		{ u.u_error = EFAULT; return; }

}	/* end k_listen */
Example #12
0
/*
 ****************************************************************
 *	Desassocia um "port" de um "endpoint"			*
 ****************************************************************
 */
void
k_unbind (int minor)
{
	ITSCB		*ip = &itscb;
	KFILE		*fp = u.u_fileptr;

	/*
	 *	Verifica qual o protocolo a utilizar
	 */
	switch (minor)
	{
		/*
		 *	Protocolo RAW
		 */
	    case RAW:
	    {
		RAW_EP		*rp, *rp_next;
		LOCK		rp_lock;

		if (fp->f_union != KF_ITNET)
			{ u.u_error = EBADF; return; }

		rp = fp->f_endpoint;

		SLEEPLOCK (&rp->rp_lock, PITNETOUT);

		if (rp->rp_state != S_BOUND)
			{ SLEEPFREE (&rp->rp_lock); u.u_error = TOUTSTATE; return; }

		delete_raw_queues (rp);

		SPINLOCK (&ip->it_rep_lock);

		rp_next = rp->rp_next;
		rp_lock = rp->rp_lock;

		memclr (rp, sizeof (RAW_EP));

		rp->rp_next  = rp_next;
		rp->rp_lock  = rp_lock;
		rp->rp_state = S_UNBOUND;

		SPINFREE (&ip->it_rep_lock);

		SLEEPFREE (&rp->rp_lock);

		break;
	    }

		/*
		 *	Protocolo UDP
		 */
	    case UDP:
	    {
		UDP_EP		*up, *up_next;
		LOCK		up_lock;

		if (fp->f_union != KF_ITNET)
			{ u.u_error = EBADF; return; }

		up = fp->f_endpoint;

		SLEEPLOCK (&up->up_lock, PITNETOUT);

		if (up->up_state != S_BOUND)
			{ SLEEPFREE (&up->up_lock); u.u_error = TOUTSTATE; return; }

		delete_udp_queues (up);

		SPINLOCK (&ip->it_uep_lock);

		up_next = up->up_next;
		up_lock = up->up_lock;

		memclr (up, sizeof (UDP_EP));

		up->up_next  = up_next;
		up->up_lock  = up_lock;
		up->up_state = S_UNBOUND;

		SPINFREE (&ip->it_uep_lock);

		SLEEPFREE (&up->up_lock);

		break;
	    }

		/*
		 *	Protocolo TCP
		 */
	    case TCP:
	    {
		TCP_EP		*tp, *tp_next;
		LOCK		tp_lock;

		if (fp->f_union != KF_ITNET)
			{ u.u_error = EBADF; return; }

		tp = fp->f_endpoint;

		SLEEPLOCK (&tp->tp_lock, PITNETOUT);

		if (tp->tp_state != S_BOUND)
			{ SLEEPFREE (&tp->tp_lock); u.u_error = TOUTSTATE; return; }

		circular_area_mrelease (tp);

		SPINLOCK (&ip->it_tep_lock);

		tp_next = tp->tp_next;
		tp_lock = tp->tp_lock;

		memclr (tp, sizeof (TCP_EP));

		tp->tp_next		 = tp_next;
		tp->tp_lock		 = tp_lock;
		tp->tp_state		 = S_UNBOUND;
		tp->tp_SRTT		 = ip->it_SRTT;
		tp->tp_max_seg_sz 	 = ip->it_MAX_SGSZ;
		tp->tp_good_wnd 	 = ip->it_GOOD_WND;
		tp->tp_max_wait		 = ip->it_WAIT;
		tp->tp_max_silence	 = ip->it_SILENCE;
		tp->tp_rnd_in.tp_rnd_sz  = ip->it_WND_SZ;
		tp->tp_rnd_out.tp_rnd_sz = ip->it_WND_SZ;
		tp->tp_last_rcv_time	 = time;

		SPINFREE (&ip->it_tep_lock);

		SLEEPFREE (&tp->tp_lock);

		break;
	    }

		/*
		 *	Protocolos INEXISTENTES
		 */
	    default:
		u.u_error = ENXIO;
		return;

	}	/* end switch */

}	/* end k_unbind */
Example #13
0
/*
 ****************************************************************
 *	Coloca o EP no local correto da fila de TCP EPs		*
 ****************************************************************
 */
void
sort_tcp_ep (TCP_EP *tp)
{
	ITSCB		*ip = &itscb;
	TCP_EP		*atp, *btp;

	SPINLOCK (&ip->it_tep_lock);

	/*
	 *	Em primeiro lugar, procura o antecessor
	 */
	for
	(	atp = NO_TCP_EP, btp = ip->it_tep_busy;
		/* abaixo */;
		atp = btp,  btp = btp->tp_next
	)
	{
		if (btp == NO_TCP_EP)
		{
#ifdef	MSG
			printf ("%g: Nao encontrei o TCP EP na fila, port = %d\n", tp->tp_my_port);
#endif	MSG
			atp = NO_TCP_EP;
			tp->tp_next = ip->it_tep_busy;
			ip->it_tep_busy = tp;

			break;
		}

		if (btp == tp)
			break;
	}

	/*
	 *	Primeiro caso: Dado endereço e porta
	 */
	if (tp->tp_dst_port != 0)
	{
#ifdef	MSG
		if (tp->tp_dst_addr == 0)
			printf ("%g: Faltando endereco, port = %d\n", tp->tp_my_port);
#endif	MSG
		/*
		 *	Primeiro caso, variante "a", conexão remota: Fácil, Coloca no início 
		 */
		if (tp->tp_dst_addr != MY_IP_ADDR)
		{
			if (ip->it_tep_busy != tp)	/* Implica atp != NO_TCP_EP */
			{
				atp->tp_next = tp->tp_next;

				tp->tp_next = ip->it_tep_busy;
				ip->it_tep_busy = tp;
			}

			SPINFREE (&ip->it_tep_lock);
			return;
		}

		/*
		 *	Primeiro caso, variante "b", conexão local: Coloca depois das remotas
		 */
		if (atp == NO_TCP_EP)
			ip->it_tep_busy = tp->tp_next;
		else
			atp->tp_next = tp->tp_next;

		for
		(	atp = NO_TCP_EP, btp = ip->it_tep_busy;
			/* abaixo */;
			atp = btp,  btp = btp->tp_next
		)
		{
			if (btp == NO_TCP_EP)
				break;

			if (btp->tp_dst_addr == 0 || btp->tp_dst_port == 0)
				break;

			if (btp->tp_dst_addr == MY_IP_ADDR)
				break;
		}

		if (atp == NO_TCP_EP)
			ip->it_tep_busy = tp;
		else
			atp->tp_next = tp;

		tp->tp_next = btp;

		SPINFREE (&ip->it_tep_lock);

		return;
	}

	/*
	 *	Segundo caso: Não dado nem endereço nem porta
	 *
	 *	Fácil: Coloca no final
	 */
	if (tp->tp_dst_addr == 0)
	{
		if (tp->tp_next != NO_TCP_EP)
		{
			if (atp == NO_TCP_EP)
				ip->it_tep_busy = tp->tp_next;
			else
				atp->tp_next = tp->tp_next;

			for (btp = tp; btp->tp_next != NO_TCP_EP; btp = btp->tp_next)
				/* vazio */;

			btp->tp_next = tp;
			tp->tp_next  = NO_TCP_EP;
		}

		SPINFREE (&ip->it_tep_lock);
		return;
	}

	/*
	 *	Terceiro caso: Dado apenas o endereço
	 *
	 *	Coloca antes do que não tem endereço nem porta
	 */
	if (atp == NO_TCP_EP)
		ip->it_tep_busy = tp->tp_next;
	else
		atp->tp_next = tp->tp_next;

	for
	(	atp = NO_TCP_EP, btp = ip->it_tep_busy;
		/* abaixo */;
		atp = btp,  btp = btp->tp_next
	)
	{
		if (btp == NO_TCP_EP)
			break;

		if (btp->tp_my_port != tp->tp_my_port)
			continue;

		if (btp->tp_dst_addr == 0)
			break;
	}

	if (atp == NO_TCP_EP)
		ip->it_tep_busy = tp;
	else
		atp->tp_next = tp;

	tp->tp_next = btp;

	SPINFREE (&ip->it_tep_lock);

}	/* end sort_tcp_ep */
Example #14
0
/*
 ****************************************************************
 *	Devolve um TCP EP para a lista livre			*
 ****************************************************************
 */
void
put_tcp_ep (register TCP_EP *tp)
{
	register ITSCB	*ip = &itscb;
	register TCP_EP *atp;

#ifdef	MSG
	if (tp == NO_TCP_EP)
	    { printf ("%g: Devolvendo EP NULO\n"); return; }
#endif	MSG

	tp->tp_state = -1;

	/*
	 *	Em primeiro lugar, tira da fila "busy"
	 */
	SPINLOCK (&ip->it_tep_lock);

	if (ip->it_tep_busy == tp)
	{
		ip->it_tep_busy = tp->tp_next;
	}
	else for (atp = ip->it_tep_busy; /* abaixo */; atp = atp->tp_next)
	{
		if (atp == NO_TCP_EP)
		{
			SPINFREE (&ip->it_tep_lock);
#ifdef	MSG
			printf ("%g: Não achei o EP na fila BUSY\n");
#endif	MSG
			return;
		}

		if (atp->tp_next == tp)
		{
			atp->tp_next = tp->tp_next;
			break;
		}
	}

	SPINFREE (&ip->it_tep_lock);

	/*
	 *	Libera a área circular
	 */
	circular_area_mrelease (tp);

	/*
	 *	Imprime o SRTT
	 */
#ifdef	MSG
	if (ip->it_list_info)
		printf ("%g: port = %d, SRTT = %d ms\n", tp->tp_my_port, tp->tp_SRTT);
#endif	MSG

	/*
	 *	Devolve o EP para a lista livre
	 */
	SPINLOCK (&ip->it_tep_lock);

	tp->tp_next = ip->it_tep_free;
	ip->it_tep_free = tp;

	ip->it_tep_count--;

	SPINFREE (&ip->it_tep_lock);

}	/* end put_tcp_ep */
Example #15
0
/*
 ****************************************************************
 *	Aceita uma conexão					*
 ****************************************************************
 */
void
k_accept (int conn_fd, const T_CALL *callp)
{
	TCP_EP		*tpl, *tpc;
	KFILE		*fp = u.u_fileptr;
	ROUTE		*rp;
	LISTENQ		*lp;
	const LISTENQ	*end_listen_q;
	T_CALL		call;
	INADDR		addr;
	seq_t		ISS;

	/*
	 *	Obtém a estrutura "call"
	 */
	if (unimove (&call, callp, sizeof (T_CALL), US) < 0)
		{ u.u_error = EFAULT; return; }

#ifdef	TST_UDATA_OPT
	if (call.opt.len != 0)
		{ u.u_error = TBADOPT; return; }

	if (call.udata.len != 0)
		{ u.u_error = TBADDATA; return; }
#endif	TST_UDATA_OPT

	/*
	 *	Obtém o endereço opcional dado pelo cliente
	 */
	if (call.addr.len != 0)
	{
		if (call.addr.len != sizeof (INADDR))
			{ u.u_error = TBADADDR; return; }

		if (unimove (&addr, call.addr.buf, sizeof (INADDR), US) < 0)
			{ u.u_error = EFAULT; return; }
	}

	/*
	 *	Analisa o "endpoint" do "listen"
	 */
	if (fp->f_union != KF_ITNET)
		{ u.u_error = EBADF; return; }

	tpl = fp->f_endpoint;

	if (tpl->tp_state != S_LISTEN)
		{ u.u_error = TOUTSTATE; return; }

	/*
	 *	Analisa o "endpoint" da conexão
	 */
	if ((fp = fget (conn_fd)) == NOKFILE)
		return;

	if ((tpc = fp->f_endpoint) == NO_TCP_EP)
		{ u.u_error = EBADF; return; }

	if (tpc == tpl)
	{
		if (tpl->tp_listen_qlen > 1)
			{ u.u_error = EBADF; return; }
	}
	else /* tpc != tpl */
	{
		if (tpc->tp_state != S_BOUND)
			{ u.u_error = TOUTSTATE; return; }
	}

	/*
	 *	Procura a seqüência na fila de LISTEN (e remove)
	 */
	SPINLOCK (&tpl->tp_inq_lock);

	call.sequence = -call.sequence;		/* Está negativa */

	for (lp = tpl->tp_listen_q, end_listen_q = lp + LISTENQ_MAXSZ; /* abaixo */; lp++)
	{
		if (lp >= end_listen_q)
			{ SPINFREE (&tpl->tp_inq_lock); u.u_error = TBADSEQ; return; }

		if (lp->tp_listen_seq == call.sequence)
			break;
	}

	/*
	 *	Utiliza as informações do LISTEN
	 */
	tpc->tp_dst_addr = lp->tp_listen_addr;
	tpc->tp_dst_port = lp->tp_listen_port;
	tpc->tp_my_addr	 = lp->tp_listen_my_addr;
	tpc->tp_rcv_irs  = lp->tp_listen_irs;

	if (lp->tp_max_seg_sz > 0)
	{
		if (tpc->tp_max_seg_sz > lp->tp_max_seg_sz)
			tpc->tp_max_seg_sz = lp->tp_max_seg_sz;

		if (tpc->tp_good_wnd > lp->tp_max_seg_sz)
			tpc->tp_good_wnd   = lp->tp_max_seg_sz;
	}

#ifdef	MSG
	if (itscb.it_list_info)
	{
		printf ("%g: my_addr = ");
		pr_itn_addr (tpc->tp_my_addr);
		printf (", dst_addr = ");
		pr_itn_addr (tpc->tp_dst_addr);
		printf (", recebi max_seg_sz = %d\n", lp->tp_max_seg_sz);
		printf
		(	"\tUsando tp_max_seg_sz = %d, tp_good_wnd = %d\n",
			tpc->tp_max_seg_sz, tpc->tp_good_wnd
		);
	}
#endif	MSG

	lp->tp_listen_seq = 0;	/* Remove */

	tpl->tp_listen_qlen--;

	SPINFREE (&tpl->tp_inq_lock);

	/*
	 *	Se o usuário forneceu o endereço, confere
	 */
	if (call.addr.len != 0)
	{
		if (tpc->tp_dst_addr != addr.a_addr || tpc->tp_dst_port != addr.a_port)
			{ u.u_error = TBADADDR; return; }
	}

	/*
	 *	Aloca a área circular para a E/S
	 */
	if (circular_area_alloc (tpc) < 0)
		return;

	/*
	 *	Inicializa as seqüências
	 */
	SLEEPLOCK (&tpc->tp_lock, PITNETOUT);

	ISS = (time << 7) | hz;		/* Gera ISS de 0 a 2 ** 32 */
	ISS <<= 8;			/* Com ciclo de +- 12 horas */
	ISS = ISS + ISS + ISS;

	tpc->tp_snd_iss = ISS;
	tpc->tp_snd_una = ISS;
	tpc->tp_snd_nxt = ISS;
	tpc->tp_snd_wnd = ISS + 1;	/* Será decidido no ACK_of_SYN */
	tpc->tp_snd_up  = ISS;
	tpc->tp_snd_psh = ISS;

   /***	tpc->tp_rcv_irs = ...; /* acima ***/
	tpc->tp_rcv_usr = tpc->tp_rcv_irs + 1;
	tpc->tp_rcv_nxt = tpc->tp_rcv_irs + 1;
	tpc->tp_rcv_wnd = tpc->tp_rcv_nxt + itscb.it_WND_SZ;
	tpc->tp_old_wnd = tpc->tp_rcv_wnd;
	tpc->tp_rcv_up  = tpc->tp_rcv_nxt;
	tpc->tp_rcv_psh = tpc->tp_rcv_nxt;

	/*
	 *	Obtém o dispositivo destino e endereço fonte
	 */
	if ((rp = get_route_entry (tpc->tp_dst_addr)) == NOROUTE)
		{ SLEEPFREE (&tpc->tp_lock); u.u_error = TNOROUTE; return; }

   /***	tpc->tp_my_addr	= rp->r_my_addr; ***/
	tpc->tp_route	= rp;

	sort_tcp_ep (tpc);

	/*
	 *	Confirma a conexão
	 */
   /***	SPINLOCK (&tpc->tp_rnd_out.tp_rnd_lock); ***/

	tpc->tp_rnd_out.tp_rnd_syn = C_SYN|C_ACK;

   /***	SPINFREE (&tpc->tp_rnd_out.tp_rnd_lock); ***/

	tpc->tp_listen_maxqlen = 0;	/* Pode ser igual a "tpl" */

	tpc->tp_state = S_SYN_RECEIVED;

	send_tcp_ctl_packet (C_SYN|C_ACK, tpc);

	SLEEPFREE (&tpc->tp_lock);

	tpc->tp_last_snd_time = time;
	tpc->tp_last_ack_time = time;

	/*
	 *	Espera chegar o ACK da confirmação de conexão
	 */
	for (EVER)
	{
		if (tpc->tp_rst)
			{ u.u_error = TLOOK; return; }

		SPINLOCK (&tpc->tp_inq_lock);

		if (tpc->tp_state == S_ESTABLISHED)
			{ SPINFREE (&tpc->tp_inq_lock); break; }

		EVENTCLEAR (&tpc->tp_inq_nempty);

		SPINFREE (&tpc->tp_inq_lock);

		EVENTWAIT (&tpc->tp_inq_nempty, PITNETIN);

	}	/* end for (EVER) */

	/*
	 *	A mudança de estado é realizada por "rcv"
	 */
   /***	tpc->tp_state = S_ESTABLISHED; ***/

	check_for_pipe_mode (tpc);

}	/* end k_accept */
Example #16
0
/*
 * Locks
 *
 */
void DT_Mdep_Lock(DT_Mdep_LockType * lock_ptr)
{
	SPINLOCK(lock_ptr);
}
Example #17
0
/*
 ****************************************************************
 *	Espera a resposta de um pedido de conexão		*
 ****************************************************************
 */
void
k_rcvconnect (T_CALL *rcvcall)
{
	KFILE		*fp = u.u_fileptr;
	TCP_EP		*tp;
	const LISTENQ	*lp;
	ROUTE		*rp;
	T_CALL		call;
	INADDR		addr;

	/*
	 *	Analisa o EP
	 */
	if (fp->f_union != KF_ITNET)
		{ u.u_error = EBADF; return; }

	tp = fp->f_endpoint;

#if (0)	/*******************************************************/
	if (tp->tp_state != S_SYN_SENT && tp->tp_state != S_ESTABLISHED)
		{ u.u_error = TOUTSTATE; return; }
#endif	/*******************************************************/

	if (tp->tp_state != S_SYN_SENT)
	{
		if (tp->tp_rst)
			{ u.u_error = TLOOK; return; }

		if (tp->tp_state != S_ESTABLISHED)
			{ u.u_error = TOUTSTATE; return; }
	}

	/*
	 *	Espera chegar a confirmação do pedido de conexão
	 */
	for (EVER)
	{
		if (tp->tp_rst)
			{ u.u_error = TLOOK; return; }

		SPINLOCK (&tp->tp_inq_lock);

		if (tp->tp_state == S_ESTABLISHED)
			{ SPINFREE (&tp->tp_inq_lock); break; }

		EVENTCLEAR (&tp->tp_inq_nempty);

		SPINFREE (&tp->tp_inq_lock);

		EVENTWAIT (&tp->tp_inq_nempty, PITNETIN);

	}	/* end for (EVER) */

	/*
	 *	A mudança de estado é realizada por "rcv"
	 */
   /***	tp->tp_state = S_ESTABLISHED; ***/

	/*
	 *	Recebe o novo endereço (alternativo) do servidor
	 */
	lp = tp->tp_listen_q;

	addr.a_addr = lp->tp_listen_addr;
	addr.a_port = lp->tp_listen_port;

	/*
	 *	Obtém o dispositivo destino e endereço fonte
	 */
	if ((rp = get_route_entry (addr.a_addr)) == NOROUTE)
		{ u.u_error = TNOROUTE; return; }

#if (0)	/*************************************/
	if (tp->tp_dst_addr != 0  &&  tp->tp_dst_addr != addr.a_addr)
		{ u.u_error = TBADADDR; return; }

	if (tp->tp_dst_port != 0  &&  tp->tp_dst_port != addr.a_port)
		{ u.u_error = TBADADDR; return; }
#endif	/*************************************/

	SLEEPLOCK (&tp->tp_lock, PITNETOUT);

	tp->tp_dst_addr = addr.a_addr;
	tp->tp_dst_port = addr.a_port;

   /***	tp->tp_my_addr	= rp->r_my_addr; ***/
	tp->tp_my_addr  = lp->tp_listen_my_addr;
	tp->tp_route	= rp;

	/*
	 *	Trata o "max_seg_sz" do bloco contendo o SYN
	 */
	if (lp->tp_max_seg_sz > 0)
	{
		if (tp->tp_max_seg_sz > lp->tp_max_seg_sz)
			tp->tp_max_seg_sz = lp->tp_max_seg_sz;

		if (tp->tp_good_wnd > lp->tp_max_seg_sz)
			tp->tp_good_wnd   = lp->tp_max_seg_sz;
	}

#ifdef	MSG
	if (itscb.it_list_info)
	{
		printf ("%g: recebi max_seg_sz = %d\n", lp->tp_max_seg_sz);
		printf
		(	"\tUsando tp_max_seg_sz = %d, tp_good_wnd = %d\n",
			tp->tp_max_seg_sz, tp->tp_good_wnd
		);
	}
#endif	MSG

	SLEEPFREE (&tp->tp_lock);

	/*
	 *	Envia o ACK da confirmação de conexão
	 */
	send_tcp_ctl_packet (C_ACK, tp);

	/*
	 *	Copia as informações para o usuário
	 */
	if (rcvcall)
	{
		if (unimove (&call, rcvcall, sizeof (T_CALL), US) < 0)
			{ u.u_error = EFAULT; return; }

		if (call.addr.maxlen < sizeof (INADDR))
			{ u.u_error = TBUFOVFLW; return; }

		if (unimove (call.addr.buf, &addr, sizeof (INADDR), SU) < 0)
			{ u.u_error = EFAULT; return; }

		call.addr.len	= sizeof (INADDR);

		call.opt.len	= 0;
		call.udata.len	= 0;
		call.sequence	= 0;

		if (unimove (rcvcall, &call, sizeof (T_CALL), SU) < 0)
			{ u.u_error = EFAULT; return; }
	}

	check_for_pipe_mode (tp);

}	/* end k_rcvconnect */
Example #18
0
EXPORT void spinlock (uptr *u) {
  SPINLOCK(u);
}