/* unmask ports here */ for (i = 0, p = srv->ports; i < srv->port_cnt; i++, p++) {
(void)tipc_hset_mod_entry(srv->hset, p->handle, mask,
&p->event_handler);
}
}
/* remove it from handle set */
rc = tipc_hset_remove_entry(srv->hset, chan->handle); if (rc != NO_ERROR) { /* the only reason for this to fail if any handle is somehow *becomesinvalid.Thereisnoreasonablewaytorecover *fromthis.
*/
TLOGE("hset_remove_entry failed (%d)\n", rc);
abort();
}
/* remove it from list */
list_delete(&chan->chan_list_node);
/* *ifwehadamaximumnumberofchannelswewillnowbebelowmaximum. *Unmaskportsforthisservicesowecancreatechannels.
*/ if (server_at_max_chan_cnt(srv)) {
set_ports_event_mask(srv, ~0u);
}
/* decrement channel count */
srv->chan_cnt--;
/* close channel */
close(chan->handle);
/* free memory */
free(chan);
/* cleanup user allocated state if any */ if (srv->ops->on_channel_cleanup && user_ctx) {
srv->ops->on_channel_cleanup(user_ctx);
}
}
TLOGD("Incoming connection on %s\n", port->cfg->name);
/* incoming connection: accept it */
rc = accept(port->handle, &peer.id); if (rc < 0) {
TLOGE("failed (%d) to accept on port %s\n", rc, port->cfg->name); goto err_accept;
}
hchan = (handle_t)rc;
if (server_at_max_chan_cnt(srv)) { /* we should not ever get here after we implement port mask */
TLOGE("too many channels for port %s\n", port->cfg->name); goto err_too_many_chan;
}
/* do access control */ if (!client_is_allowed(port->cfg->acl, &peer.id)) {
TLOGE("access denied on port %s\n", port->cfg->name); goto err_access;
}
/* add new channel to handle set */
rc = tipc_hset_add_entry(srv->hset, hchan, ~0u, &chan->event_handler); if (rc != NO_ERROR) {
TLOGE("failed (%d) to add chan to hset\n", rc); goto err_hset_add;
}
/* invoke on_connect handler if any */ if (srv->ops->on_connect) { if (peer->kind != TRUSTY_PEER_ID_KIND_UUID) {
TLOGE("unsupported peer kind %" PRIx64 " passed to on_connect on port %s. " "Did you mean to implement on_connect_peer_id?\n",
peer->kind, port->cfg->name); goto err_unwrap_uuid_peer;
} if (peer_len != sizeof(struct trusty_peer_id_uuid)) {
TLOGE("unexpected peer_len %zu (expected %zu) passed to on_connect " "for kind %" PRIx64 " (port %s). Do kernel and userspace have mismatched " "versions?\n",
peer_len, sizeof(struct trusty_peer_id_uuid), peer->kind,
port->cfg->name); goto err_unwrap_uuid_peer;
}
rc = srv->ops->on_connect(port->cfg, chan->handle,
(struct uuid*)&peer->data, &user_ctx); if (rc < 0) {
TLOGE("on_connect failed (%d) on port %s\n", rc, port->cfg->name); goto err_on_connect;
}
} if (srv->ops->on_connect_peer_id) {
rc = srv->ops->on_connect_peer_id(port->cfg, chan->handle, peer,
peer_len, &user_ctx); if (rc < 0) {
TLOGE("on_connect_peer_id failed (%d) on port %s\n", rc,
port->cfg->name); goto err_on_connect;
}
}
/* attach context provided by caller */
chan->user_ctx = user_ctx;
/* add it to the list */
list_add_tail(&srv->chan_list, &chan->chan_list_node);
srv->chan_cnt++;
/* mask all ports if max number of connections has been reached */ if (server_at_max_chan_cnt(srv)) {
set_ports_event_mask(srv, 0u);
}
TLOGD("got connection on %s\n", port->cfg->name); return NO_ERROR;
if (IS_ERR(hset)) {
TLOGE("invalid handle set (%d)\n", PTR_ERR(hset)); return ERR_INVALID_ARGS;
}
if (!hset || !ports || !num_ports) {
TLOGE("required parameter is missing\n"); return ERR_INVALID_ARGS;
}
if (!is_valid_tipc_srv_ops(ops)) {
TLOGE("Service operations failed validation\n"); return ERR_INVALID_ARGS;
}
/* allocate new service */
srv = calloc(1, sizeof(struct tipc_srv) + sizeof(struct tipc_port_ctx) * num_ports); if (!srv) { return ERR_NO_MEMORY;
}
/* and initialize it */
srv->hset = hset;
srv->port_cnt = num_ports;
srv->max_chan_cnt = max_chan_cnt;
list_initialize(&srv->chan_list);
srv->ops = ops; for (i = 0; i < num_ports; i++) {
srv->ports[i].handle = INVALID_IPC_HANDLE;
}
/* for each port */ for (i = 0; i < num_ports; i++) {
TLOGD("Initialize port: %s\n", ports[i].name);
port = &srv->ports[i];
if (!ports[i].acl) {
TLOGE("ACL is required to create port\n");
rc = ERR_INVALID_ARGS; goto err_no_acl;
}
/* create port */
rc = port_create(ports[i].name, ports[i].msg_queue_len,
ports[i].msg_max_size, ports[i].acl->flags); if (rc < 0) {
TLOGE("failed (%d) to create port\n", rc); goto err_port_create;
}
port->handle = (handle_t)rc;
/* init event handler and other pointers */
port->cfg = &ports[i];
port->event_handler.proc = port_event_handler_proc;
port->event_handler.priv = port;
port->srv = srv;
/* and add it to the handle set */
rc = tipc_hset_add_entry(hset, port->handle, ~0u, &port->event_handler); if (rc < 0) {
TLOGE("failed (%d) to register port\n", rc); goto err_hset_add;
}
}
setup_mailbox(ports, num_ports); if (ports_out) { for (i = 0; i < num_ports; i++) {
ports_out[i] = &srv->ports[i];
}
} return0;
err_hset_add:
err_port_create:
err_no_acl: /* kill all ports we have created so far */ for (i = 0; i < num_ports; i++) { if (srv->ports[i].handle != INVALID_IPC_HANDLE) { /* Note: closing handle also removes it from all handle sets */
rc = close(srv->ports[i].handle);
assert(rc == 0);
}
} /* then free service */
free(srv);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.