예제 #1
0
파일: tcp_usr.c 프로젝트: fjanssen/Car2X
int
tcp_attach(struct socket * so)
{
   struct tcpcb * tp;
   struct inpcb * inp;
   int   error;

   if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) 
   {
      error = soreserve(so, tcp_sendspace, tcp_recvspace);
      if (error)
         return (error);
   }
   error = in_pcballoc(so, &tcb);
   if (error)
      return (error);
   inp = sotoinpcb(so);
   tp = tcp_newtcpcb(inp);
   if (tp == 0) 
   {
      int   nofd  =  so->so_state   &  SS_NOFDREF; /* XXX */

      so->so_state &= ~SS_NOFDREF;     /* don't free the socket yet */
      in_pcbdetach(inp);
      so->so_state |= nofd;
      return (ENOBUFS);
   }
   tp->t_state = TCPS_CLOSED;
   return (0);
}
/*
 * Attach TCP protocol to socket, allocating
 * internet protocol control block, tcp control block,
 * bufer space, and entering LISTEN state if to accept connections.
 */
static int
tcp_attach(struct socket *so)
{
	struct tcpcb *tp;
	struct inpcb *inp;
	int error;
#ifdef INET6
	int isipv6 = INP_CHECK_SOCKAF(so, AF_INET6) != 0;
#endif

	//printf("tcp_attach: called so->so_snd=0x%lx\n", (long)&so->so_snd);
	//printf("tcp_attach: called so->so_rcv=0x%lx\n", (long)&so->so_rcv);
	if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
	//printf("tcp_attach: called 2\n");
		error = soreserve(so, tcp_sendspace, tcp_recvspace);
		if (error)
			return (error);
	}
	//printf("tcp_attach: called 2\n");
	so->so_rcv.sb_flags |= SB_AUTOSIZE;
	so->so_snd.sb_flags |= SB_AUTOSIZE;
	INP_INFO_WLOCK(&tcbinfo);
	error = in_pcballoc(so, &tcbinfo);
	if (error) {
		INP_INFO_WUNLOCK(&tcbinfo);
		return (error);
	}
	inp = sotoinpcb(so);
#ifdef INET6
	if (isipv6) {
		inp->inp_vflag |= INP_IPV6;
		inp->in6p_hops = -1;	/* use kernel default */
	}
	else
#endif
	inp->inp_vflag |= INP_IPV4;
	//printf("tcp_attach: called 5\n");
	tp = tcp_newtcpcb(inp);
	if (tp == NULL) {
#ifdef INET6
		if (isipv6) {
			in6_pcbdetach(inp);
			in6_pcbfree(inp);
		} else {
#endif
			in_pcbdetach(inp);
			in_pcbfree(inp);
#ifdef INET6
		}
#endif
		INP_INFO_WUNLOCK(&tcbinfo);
		return (ENOBUFS);
	}
	tp->t_state = TCPS_CLOSED;
	INP_UNLOCK(inp);
	INP_INFO_WUNLOCK(&tcbinfo);
	//printf("tcp_attach: called 10\n");
	return (0);
}
예제 #3
0
/*
 * Attach TCP protocol to socket, allocating internet protocol control
 * block, tcp control block, bufer space, and entering LISTEN state
 * if to accept connections.
 */
static int
tcp_attach(struct socket *so, struct pru_attach_info *ai)
{
	struct tcpcb *tp;
	struct inpcb *inp;
	int error;
	int cpu;
#ifdef INET6
	int isipv6 = INP_CHECK_SOCKAF(so, AF_INET6) != 0;
#endif

	if (so->so_snd.ssb_hiwat == 0 || so->so_rcv.ssb_hiwat == 0) {
		lwkt_gettoken(&so->so_rcv.ssb_token);
		error = soreserve(so, tcp_sendspace, tcp_recvspace,
				  ai->sb_rlimit);
		lwkt_reltoken(&so->so_rcv.ssb_token);
		if (error)
			return (error);
	}
	atomic_set_int(&so->so_rcv.ssb_flags, SSB_AUTOSIZE);
	atomic_set_int(&so->so_snd.ssb_flags, SSB_AUTOSIZE);
	cpu = mycpu->gd_cpuid;

	/*
	 * Set the default port for protocol processing. This will likely
	 * change when we connect.
	 */
	error = in_pcballoc(so, &tcbinfo[cpu]);
	if (error)
		return (error);
	inp = so->so_pcb;
#ifdef INET6
	if (isipv6) {
		inp->inp_vflag |= INP_IPV6;
		inp->in6p_hops = -1;	/* use kernel default */
	}
	else
#endif
	inp->inp_vflag |= INP_IPV4;
	tp = tcp_newtcpcb(inp);
	if (tp == NULL) {
		/*
		 * Make sure the socket is destroyed by the pcbdetach.
		 */
		soreference(so);
#ifdef INET6
		if (isipv6)
			in6_pcbdetach(inp);
		else
#endif
		in_pcbdetach(inp);
		sofree(so);	/* from ref above */
		return (ENOBUFS);
	}
	tp->t_state = TCPS_CLOSED;
	return (0);
}
예제 #4
0
static int
udp6_attach(struct socket *so, int proto, struct thread *td)
{
	struct inpcb *inp;
	struct inpcbinfo *pcbinfo;
	int error;

	pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol);
	inp = sotoinpcb(so);
	KASSERT(inp == NULL, ("udp6_attach: inp != NULL"));

	if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
		error = soreserve(so, udp_sendspace, udp_recvspace);
		if (error)
			return (error);
	}
	INP_INFO_WLOCK(pcbinfo);
	error = in_pcballoc(so, pcbinfo);
	if (error) {
		INP_INFO_WUNLOCK(pcbinfo);
		return (error);
	}
	inp = (struct inpcb *)so->so_pcb;
	inp->inp_vflag |= INP_IPV6;
	if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0)
		inp->inp_vflag |= INP_IPV4;
	inp->in6p_hops = -1;	/* use kernel default */
	inp->in6p_cksum = -1;	/* just to be sure */
	/*
	 * XXX: ugly!!
	 * IPv4 TTL initialization is necessary for an IPv6 socket as well,
	 * because the socket may be bound to an IPv6 wildcard address,
	 * which may match an IPv4-mapped IPv6 address.
	 */
	inp->inp_ip_ttl = V_ip_defttl;

	error = udp_newudpcb(inp);
	if (error) {
		in_pcbdetach(inp);
		in_pcbfree(inp);
		INP_INFO_WUNLOCK(pcbinfo);
		return (error);
	}
	INP_WUNLOCK(inp);
	INP_INFO_WUNLOCK(pcbinfo);
	return (0);
}
예제 #5
0
/*
 * Attach TCP protocol to socket, allocating
 * internet protocol control block, tcp control block,
 * bufer space, and entering LISTEN state if to accept connections.
 */
static int
tcp_attach(struct socket *so)
{
	struct tcpcb *tp;
	struct inpcb *inp;
	int error;

	if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
		error = soreserve(so, tcp_sendspace, tcp_recvspace);
		if (error)
			return (error);
	}
	so->so_rcv.sb_flags |= SB_AUTOSIZE;
	so->so_snd.sb_flags |= SB_AUTOSIZE;
	INP_INFO_WLOCK(&V_tcbinfo);
	error = in_pcballoc(so, &V_tcbinfo);
	if (error) {
		INP_INFO_WUNLOCK(&V_tcbinfo);
		return (error);
	}
	inp = sotoinpcb(so);
#ifdef INET6
	if (inp->inp_vflag & INP_IPV6PROTO) {
		inp->inp_vflag |= INP_IPV6;
		inp->in6p_hops = -1;	/* use kernel default */
	}
	else
#endif
	inp->inp_vflag |= INP_IPV4;
	tp = tcp_newtcpcb(inp);
	if (tp == NULL) {
		in_pcbdetach(inp);
		in_pcbfree(inp);
		INP_INFO_WUNLOCK(&V_tcbinfo);
		return (ENOBUFS);
	}
	tp->t_state = TCPS_CLOSED;
	INP_WUNLOCK(inp);
	INP_INFO_WUNLOCK(&V_tcbinfo);
	return (0);
}
예제 #6
0
static void
udp6_attach(netmsg_t msg)
{
	struct socket *so = msg->attach.base.nm_so;
	struct pru_attach_info *ai = msg->attach.nm_ai;
	struct inpcb *inp;
	int error;

	inp = so->so_pcb;
	if (inp != NULL) {
		error = EINVAL;
		goto out;
	}

	if (so->so_snd.ssb_hiwat == 0 || so->so_rcv.ssb_hiwat == 0) {
		error = soreserve(so, udp_sendspace, udp_recvspace,
		    ai->sb_rlimit);
		if (error)
			goto out;
	}

	error = in_pcballoc(so, &udbinfo[0]);
	if (error)
		goto out;

	inp = (struct inpcb *)so->so_pcb;
	inp->in6p_hops = -1;	/* use kernel default */
	inp->in6p_cksum = -1;	/* just to be sure */
	/*
	 * XXX: ugly!!
	 * IPv4 TTL initialization is necessary for an IPv6 socket as well,
	 * because the socket may be bound to an IPv6 wildcard address,
	 * which may match an IPv4-mapped IPv6 address.
	 */
	inp->inp_ip_ttl = ip_defttl;
	error = 0;
out:
	lwkt_replymsg(&msg->attach.base.lmsg, error);
}
예제 #7
0
static int
udp_attach(struct socket *so, int proto, struct thread *td)
{
	struct inpcb *inp;
	struct inpcbinfo *pcbinfo;
	int error;

	pcbinfo = get_inpcbinfo(so->so_proto->pr_protocol);
	inp = sotoinpcb(so);
	KASSERT(inp == NULL, ("udp_attach: inp != NULL"));
	error = soreserve(so, udp_sendspace, udp_recvspace);
	if (error)
		return (error);
	INP_INFO_WLOCK(pcbinfo);
	error = in_pcballoc(so, pcbinfo);
	if (error) {
		INP_INFO_WUNLOCK(pcbinfo);
		return (error);
	}

	inp = sotoinpcb(so);
	inp->inp_vflag |= INP_IPV4;
	inp->inp_ip_ttl = V_ip_defttl;

	error = udp_newudpcb(inp);
	if (error) {
		in_pcbdetach(inp);
		in_pcbfree(inp);
		INP_INFO_WUNLOCK(pcbinfo);
		return (error);
	}

	INP_WUNLOCK(inp);
	INP_INFO_WUNLOCK(pcbinfo);
	return (0);
}