static int send_obj_unreachable(struct sk_buff *rskb)
{
    const struct phonethdr *oph = pn_hdr(rskb);
    const struct phonetmsg *opm = pn_msg(rskb);
    struct phonetmsg resp;

    memset(&resp, 0, sizeof(resp));
    resp.pn_trans_id = opm->pn_trans_id;
    resp.pn_msg_id = PN_COMMON_MESSAGE;
    if (oph->pn_res == PN_PREFIX) {
        resp.pn_e_res_id = opm->pn_e_res_id;
        resp.pn_e_submsg_id = PN_COMM_ISA_ENTITY_NOT_REACHABLE_RESP;
        resp.pn_e_orig_msg_id = opm->pn_msg_id;
        resp.pn_e_status = 0;
    } else {
        resp.pn_submsg_id = PN_COMM_ISA_ENTITY_NOT_REACHABLE_RESP;
        resp.pn_orig_msg_id = opm->pn_msg_id;
        resp.pn_status = 0;
    }
    return pn_raw_send(&resp, sizeof(resp), rskb->dev,
                       pn_object(oph->pn_sdev, oph->pn_sobj),
                       pn_object(oph->pn_rdev, oph->pn_robj),
                       oph->pn_res);
}
Пример #2
0
/* allocate port for a socket */
int pn_sock_get_port(struct sock *sk, unsigned short sport)
{
	static int port_cur;
	struct net *net = sock_net(sk);
	struct pn_sock *pn = pn_sk(sk);
	struct sockaddr_pn try_sa;
	struct sock *tmpsk;

	memset(&try_sa, 0, sizeof(struct sockaddr_pn));
	try_sa.spn_family = AF_PHONET;
	WARN_ON(!mutex_is_locked(&port_mutex));
	if (!sport) {
		/* search free port */
		int port, pmin, pmax;

		phonet_get_local_port_range(&pmin, &pmax);
		for (port = pmin; port <= pmax; port++) {
                        //Patch for hashtable
			port_cur += PN_HASHSIZE;
			if (port_cur < pmin || port_cur > pmax)
				port_cur = pmin;

			pn_sockaddr_set_port(&try_sa, port_cur);
			tmpsk = pn_find_sock_by_sa(net, &try_sa);
			if (tmpsk == NULL) {
				sport = port_cur;
				goto found;
			} else
				sock_put(tmpsk);
		}
	} else {
		/* try to find specific port */
		pn_sockaddr_set_port(&try_sa, sport);
		tmpsk = pn_find_sock_by_sa(net, &try_sa);
		if (tmpsk == NULL)
			/* No sock there! We can use that port... */
			goto found;
		else
			sock_put(tmpsk);
	}
	/* the port must be in use already */
	return -EADDRINUSE;

found:
	pn->sobject = pn_object(pn_addr(pn->sobject), sport);
	return 0;
}
Пример #3
0
static int pn_socket_bind(struct socket *sock, struct sockaddr *addr, int len)
{
	struct sock *sk = sock->sk;
	struct pn_sock *pn = pn_sk(sk);
	struct sockaddr_pn *spn = (struct sockaddr_pn *)addr;
	int err;
	u16 handle;
	u8 saddr;

	if (sk->sk_prot->bind)
		return sk->sk_prot->bind(sk, addr, len);

	if (len < sizeof(struct sockaddr_pn))
		return -EINVAL;
	if (spn->spn_family != AF_PHONET)
		return -EAFNOSUPPORT;

	handle = pn_sockaddr_get_object((struct sockaddr_pn *)addr);
	saddr = pn_addr(handle);
	if (saddr && phonet_address_lookup(sock_net(sk), saddr))
		return -EADDRNOTAVAIL;

	lock_sock(sk);
	if (sk->sk_state != TCP_CLOSE || pn_port(pn->sobject)) {
		err = -EINVAL; /* attempt to rebind */
		goto out;
	}
	WARN_ON(sk_hashed(sk));
	mutex_lock(&port_mutex);
	err = sk->sk_prot->get_port(sk, pn_port(handle));
	if (err)
		goto out_port;

	/* get_port() sets the port, bind() sets the address if applicable */
	pn->sobject = pn_object(saddr, pn_port(pn->sobject));
	pn->resource = spn->spn_resource;

	/* Enable RX on the socket */
	sk->sk_prot->hash(sk);
out_port:
	mutex_unlock(&port_mutex);
out:
	release_sock(sk);
	return err;
}
/*
 * Create a Phonet header for the skb and send it out. Returns
 * non-zero error code if failed. The skb is freed then.
 */
int pn_skb_send(struct sock *sk, struct sk_buff *skb,
		const struct sockaddr_pn *target)
{
	struct net *net = sock_net(sk);
	struct net_device *dev;
	struct pn_sock *pn = pn_sk(sk);
	int err;
	u16 src;
	u8 daddr = pn_sockaddr_get_addr(target), saddr = PN_NO_ADDR;

	err = -EHOSTUNREACH;
	if (sk->sk_bound_dev_if)
		dev = dev_get_by_index(net, sk->sk_bound_dev_if);
	else if (phonet_address_lookup(net, daddr) == 0) {
		dev = phonet_device_get(net);
		skb->pkt_type = PACKET_LOOPBACK;
	} else
		dev = phonet_route_output(net, daddr);

	if (!dev || !(dev->flags & IFF_UP))
		goto drop;

	saddr = phonet_address_get(dev, daddr);
	if (saddr == PN_NO_ADDR)
		goto drop;

	src = pn->sobject;
	if (!pn_addr(src))
		src = pn_object(saddr, pn_obj(src));

	err = pn_send(skb, dev, pn_sockaddr_get_object(target),
			src, pn_sockaddr_get_resource(target), 0);
	dev_put(dev);
	return err;

drop:
	kfree_skb(skb);
	if (dev)
		dev_put(dev);
	return err;
}
Пример #5
0
tracker sender::send(const message &message) {
    uint64_t id = ++tag_counter;
    pn_delivery_t *dlv =
        pn_delivery(pn_object(), pn_dtag(reinterpret_cast<const char*>(&id), sizeof(id)));
    std::vector<char> buf;
    message.encode(buf);
    assert(!buf.empty());
    pn_link_send(pn_object(), &buf[0], buf.size());
    pn_link_advance(pn_object());
    if (pn_link_snd_settle_mode(pn_object()) == PN_SND_SETTLED)
        pn_delivery_settle(dlv);
    if (!pn_link_credit(pn_object()))
        link_context::get(pn_object()).draining = false;
    return make_wrapper<tracker>(dlv);
}
Пример #6
0
static int pn_socket_ioctl(struct socket *sock, unsigned int cmd,
				unsigned long arg)
{
	struct sock *sk = sock->sk;
	struct pn_sock *pn = pn_sk(sk);

	if (cmd == SIOCPNGETOBJECT) {
		struct net_device *dev;
		u16 handle;
		u8 saddr;

		if (get_user(handle, (__u16 __user *)arg))
			return -EFAULT;

		lock_sock(sk);
		if (sk->sk_bound_dev_if)
			dev = dev_get_by_index(sock_net(sk),
						sk->sk_bound_dev_if);
		else
			dev = phonet_device_get(sock_net(sk));
		if (dev && (dev->flags & IFF_UP))
			saddr = phonet_address_get(dev, pn_addr(handle));
		else
			saddr = PN_NO_ADDR;
		release_sock(sk);

		if (dev)
			dev_put(dev);
		if (saddr == PN_NO_ADDR)
			return -EHOSTUNREACH;

		handle = pn_object(saddr, pn_port(pn->sobject));
		return put_user(handle, (__u16 __user *)arg);
	}

	return sk->sk_prot->ioctl(sk, cmd, arg);
}
Пример #7
0
sender session::open_sender(const std::string &addr, const link_options &lo) {
    sender snd = pn_sender(pn_object(), next_link_name(connection()).c_str());
    snd.local_target().address(addr);
    snd.open(lo);
    return snd;
}
Пример #8
0
void session::open() {
    pn_session_open(pn_object());
}
Пример #9
0
connection session::connection() const {
    return pn_session_connection(pn_object());
}
Пример #10
0
bool session::closed() const { return ::closed(pn_session_state(pn_object())); }
Пример #11
0
void link::close(const error_condition& condition) {
    set_error_condition(condition, pn_link_condition(pn_object()));
    close();
}
Пример #12
0
condition session::remote_condition() const {
    return condition(pn_session_remote_condition(pn_object()));
}
Пример #13
0
sender tracker::sender() const { return pn_delivery_link(pn_object()); }
Пример #14
0
void link::close() {
    pn_link_close(pn_object());
}
Пример #15
0
void link::detach() {
    pn_link_detach(pn_object());
}
Пример #16
0
session session::next(endpoint::state s) const
{
    return pn_session_next(pn_object(), s);
}
Пример #17
0
void link::attach() {
    pn_link_open(pn_object());
}
Пример #18
0
sender session::create_sender(const std::string& name) {
    return pn_sender(pn_object(), set_name(name, this).c_str());
}
Пример #19
0
void sender::return_credit() {
    link_context &lctx = link_context::get(pn_object());
    lctx.draining = false;
    pn_link_drained(pn_object());
}
Пример #20
0
bool link::active() const { return ::active(pn_link_state(pn_object())); }
Пример #21
0
endpoint::state session::state() const { return pn_session_state(pn_object()); }
Пример #22
0
bool session::active() const { return ::active(pn_session_state(pn_object())); }
Пример #23
0
condition session::local_condition() const {
    return condition(pn_session_condition(pn_object()));
}
Пример #24
0
class connection link::connection() const {
    return make_wrapper(pn_session_connection(pn_link_session(pn_object())));
}
Пример #25
0
bool link::uninitialized() const { return ::uninitialized(pn_link_state(pn_object())); }
Пример #26
0
class session link::session() const {
    return make_wrapper(pn_link_session(pn_object()));
}
Пример #27
0
void session::close(const error_condition& condition) {
    set_error_condition(condition, pn_session_condition(pn_object()));
    close();
}
Пример #28
0
error_condition link::error() const {
    return make_wrapper(pn_link_remote_condition(pn_object()));
}
Пример #29
0
std::string link::name() const { return str(pn_link_name(pn_object()));}
Пример #30
0
bool link::closed() const { return ::closed(pn_link_state(pn_object())); }