ContactSection ContactSection::AddItem( const std::shared_ptr<ContactItem>& item) const { OT_ASSERT(item); const bool specialCaseScope = (proto::CONTACTSECTION_SCOPE == section_); if (specialCaseScope) { return add_scope(item); } const auto& groupID = item->Type(); const bool groupExists = groups_.count(groupID); auto map = groups_; if (groupExists) { auto& existing = map.at(groupID); OT_ASSERT(existing); existing.reset(new ContactGroup(existing->AddItem(item))); } else { map[groupID].reset(new ContactGroup(nym_, section_, item)); } auto version = proto::RequiredVersion(section_, item->Type(), version_); return ContactSection(nym_, version, version, section_, map); }
struct scope * scopes_open(struct subscriber *subscriber, struct scope *super_scope, scope_id_t scope_id, void *specs, data_len_t spec_len, scope_flags_t flags, scope_ttl_t ttl) { /* check if the application is subscribed */ if (!IS_SUBSCRIBED(subscriber)) { return NULL; } /* check if the scope id is already known */ if (lookup_scope_id(scope_id) != NULL) { return NULL; } /* check if the super scope is known */ if (lookup_scope_id(super_scope->scope_id) == NULL) { return NULL; } /* check if memory is available */ struct scope *scope = allocate_scope(spec_len); if (scope == NULL) { return NULL; } /* fill in the scope information */ scope->scope_id = scope_id; scope->super_scope_id = super_scope->scope_id; scope->owner = subscriber; scope->ttl = ttl; scope->status = SCOPES_STATUS_CREATOR; scope->flags = flags; scope->spec_len = spec_len; /* copy the specification */ memcpy(scope->specs, specs, spec_len); /* add the scope to the scopes list */ add_scope(scope); /* join the scope */ join_scope(scope); /* announce the creation of the scope on the network */ // announce_scope_open(scope); ctimer_set(&(tmp_timer), CLOCK_SECOND, (void(*)(void *)) announce_scope_open, scope); /* return a reference to the new scope */ return scope; }
int rt_Set(struct bundle *bundle, int cmd, const struct ncprange *dst, const struct ncpaddr *gw, int bang, int quiet) { struct rtmsg rtmes; int s, nb, wb; char *cp; const char *cmdstr; struct sockaddr_storage sadst, samask, sagw; int result = 1; if (bang) cmdstr = (cmd == RTM_ADD ? "Add!" : "Delete!"); else cmdstr = (cmd == RTM_ADD ? "Add" : "Delete"); s = ID0socket(PF_ROUTE, SOCK_RAW, 0); if (s < 0) { log_Printf(LogERROR, "rt_Set: socket(): %s\n", strerror(errno)); return result; } memset(&rtmes, '\0', sizeof rtmes); rtmes.m_rtm.rtm_version = RTM_VERSION; rtmes.m_rtm.rtm_type = cmd; rtmes.m_rtm.rtm_addrs = RTA_DST; rtmes.m_rtm.rtm_seq = ++bundle->routing_seq; rtmes.m_rtm.rtm_pid = getpid(); rtmes.m_rtm.rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC; if (cmd == RTM_ADD) { if (bundle->ncp.cfg.sendpipe > 0) { rtmes.m_rtm.rtm_rmx.rmx_sendpipe = bundle->ncp.cfg.sendpipe; rtmes.m_rtm.rtm_inits |= RTV_SPIPE; } if (bundle->ncp.cfg.recvpipe > 0) { rtmes.m_rtm.rtm_rmx.rmx_recvpipe = bundle->ncp.cfg.recvpipe; rtmes.m_rtm.rtm_inits |= RTV_RPIPE; } } ncprange_getsa(dst, &sadst, &samask); #if defined(__KAME__) && !defined(NOINET6) add_scope((struct sockaddr *)&sadst, bundle->iface->index); #endif cp = rtmes.m_space; cp += memcpy_roundup(cp, &sadst, sadst.ss_len); if (cmd == RTM_ADD) { if (gw == NULL) { log_Printf(LogERROR, "rt_Set: Program error\n"); close(s); return result; } ncpaddr_getsa(gw, &sagw); #if defined(__KAME__) && !defined(NOINET6) add_scope((struct sockaddr *)&sagw, bundle->iface->index); #endif if (ncpaddr_isdefault(gw)) { if (!quiet) log_Printf(LogERROR, "rt_Set: Cannot add a route with" " gateway 0.0.0.0\n"); close(s); return result; } else { cp += memcpy_roundup(cp, &sagw, sagw.ss_len); rtmes.m_rtm.rtm_addrs |= RTA_GATEWAY; } } if (!ncprange_ishost(dst)) { cp += memcpy_roundup(cp, &samask, samask.ss_len); rtmes.m_rtm.rtm_addrs |= RTA_NETMASK; } nb = cp - (char *)&rtmes; rtmes.m_rtm.rtm_msglen = nb; wb = ID0write(s, &rtmes, nb); if (wb < 0) { log_Printf(LogTCPIP, "rt_Set failure:\n"); log_Printf(LogTCPIP, "rt_Set: Cmd = %s\n", cmdstr); log_Printf(LogTCPIP, "rt_Set: Dst = %s\n", ncprange_ntoa(dst)); if (gw != NULL) log_Printf(LogTCPIP, "rt_Set: Gateway = %s\n", ncpaddr_ntoa(gw)); failed: if (cmd == RTM_ADD && (rtmes.m_rtm.rtm_errno == EEXIST || (rtmes.m_rtm.rtm_errno == 0 && errno == EEXIST))) { if (!bang) { log_Printf(LogWARN, "Add route failed: %s already exists\n", ncprange_ntoa(dst)); result = 0; /* Don't add to our dynamic list */ } else { rtmes.m_rtm.rtm_type = cmd = RTM_CHANGE; if ((wb = ID0write(s, &rtmes, nb)) < 0) goto failed; } } else if (cmd == RTM_DELETE && (rtmes.m_rtm.rtm_errno == ESRCH || (rtmes.m_rtm.rtm_errno == 0 && errno == ESRCH))) { if (!bang) log_Printf(LogWARN, "Del route failed: %s: Non-existent\n", ncprange_ntoa(dst)); } else if (rtmes.m_rtm.rtm_errno == 0) { if (!quiet || errno != ENETUNREACH) log_Printf(LogWARN, "%s route failed: %s: errno: %s\n", cmdstr, ncprange_ntoa(dst), strerror(errno)); } else log_Printf(LogWARN, "%s route failed: %s: %s\n", cmdstr, ncprange_ntoa(dst), strerror(rtmes.m_rtm.rtm_errno)); } if (log_IsKept(LogDEBUG)) { char gwstr[40]; if (gw) snprintf(gwstr, sizeof gwstr, "%s", ncpaddr_ntoa(gw)); else snprintf(gwstr, sizeof gwstr, "<none>"); log_Printf(LogDEBUG, "wrote %d: cmd = %s, dst = %s, gateway = %s\n", wb, cmdstr, ncprange_ntoa(dst), gwstr); } close(s); return result; }
void scopes_receive(struct scopes_msg_generic *gmsg) { #ifdef DEBUG_SCOPES printf("scope_id %d, type%d\n", gmsg->scope_id, gmsg->type); #endif DEBUG_SCOPES switch (gmsg->type) { case SCOPES_MSG_OPEN: { /* cast the message to the correct type */ struct scopes_msg_open *msg = (struct scopes_msg_open *) gmsg; struct scope *super_scope = lookup_scope_id(msg->scope_id); struct scope *new_scope = lookup_scope_id(msg->sub_scope_id); /* check if the super scope is known */ if (super_scope != NULL) { /* check if the node is a member in the super scope */ if (HAS_STATUS(super_scope, SCOPES_STATUS_MEMBER)) { /* check if the new scope is known */ if (new_scope != NULL) { /* check if the new scope is the super scope's sub scope */ if (ARE_LINKED(super_scope, new_scope) && !HAS_STATUS(new_scope, SCOPES_STATUS_CREATOR)) { /* calculate the position of the specification */ void *specs_msg_ptr = (void *) ((uint8_t *) gmsg + sizeof(struct scopes_msg_open)); /* check membership */ int should_be_member = membership->check(specs_msg_ptr, msg->spec_len); /* check if the timer should be reset */// XXX: added isforwarder for aggregation if (should_be_member || msg->flags & SCOPES_FLAG_DYNAMIC || is_forwarder( msg->sub_scope_id)) { /* reset the sub scope's TTL timer */ reset_scope_timer(new_scope); } else { /* remove the scope */ remove_scope(new_scope); } } } else { /* check if the owner exists on this node and is subscribed */ struct subscriber *owner = lookup_subscriber_id( msg->owner_sid); if (owner != NULL && IS_SUBSCRIBED(owner)) { /* calculate the position of the specification */ void *specs_msg_ptr = (void *) ((uint8_t *) packetbuf_dataptr() + sizeof(struct scopes_msg_open)); /* check membership */ int should_be_member = membership->check(specs_msg_ptr, msg->spec_len); /* add the scope if the node meets the membership criteria or if the scope is a dynamic scope */// XXX: added isforwarder for aggregation if (should_be_member || msg->flags & SCOPES_FLAG_DYNAMIC || is_forwarder( msg->sub_scope_id)) { /* try to get memory for the new scope */ new_scope = allocate_scope(msg->spec_len); /* check if memory could be obtained */ if (new_scope != NULL) { /* fill in the scope information */ new_scope->scope_id = msg->sub_scope_id; new_scope->super_scope_id = msg->scope_id; new_scope->owner = owner; new_scope->ttl = msg->ttl; new_scope->status = SCOPES_STATUS_NONE; new_scope->flags = msg->flags; new_scope->spec_len = msg->spec_len; /* copy the specification */ memcpy(new_scope->specs, specs_msg_ptr, msg->spec_len); /* add the scope to the scopes list */ add_scope(new_scope); /* join if the node should be a member */ if (should_be_member) { join_scope(new_scope); } } } } } } } } break; case SCOPES_MSG_CLOSE: { /* cast the message to the correct type */ struct scopes_msg_close *msg = (struct scopes_msg_close *) gmsg; struct scope *super_scope = lookup_scope_id(msg->scope_id); struct scope *sub_scope = lookup_scope_id(msg->sub_scope_id); /* check if the scope should be removed */ if (super_scope != NULL && sub_scope != NULL && ARE_LINKED(super_scope, sub_scope) && !HAS_STATUS(sub_scope, SCOPES_STATUS_CREATOR)) { /* remove the scope */ remove_scope(sub_scope); } } break; case SCOPES_MSG_DATA: { /* cast the message to the correct type */ struct scopes_msg_data *msg = (struct scopes_msg_data *) gmsg; struct scope *scope = lookup_scope_id(msg->scope_id); /* check if the scope is known */ if (scope != NULL) { /* check if the node is a member */ // if (HAS_STATUS(scope, SCOPES_STATUS_MEMBER)) { // XXX: removed for aggregation support /* check if the message should be delivered */ if ((msg->to_creator /*&& HAS_STATUS(scope, SCOPES_STATUS_CREATOR) // XXX: commented for AGGREGATION support*/) || (!(msg->to_creator) && !HAS_STATUS(scope, SCOPES_STATUS_CREATOR) && HAS_STATUS(scope, SCOPES_STATUS_MEMBER) /* // XXX: added for AGGREGATION support */)) { /* check if the owner is subscribed */ if (IS_SUBSCRIBED(scope->owner)) { /* calculate the position of the payload */ void *payload_ptr = (void *) ((uint8_t *) gmsg + sizeof(struct scopes_msg_data)); /* notify the owner */ CALLBACK(scope->owner, recv(scope, payload_ptr, msg->data_len)); } } // } } else { // with no scope entry it is a forwarder! or not :( // XXX: added for aggregation support if (is_forwarder(msg->scope_id) && msg->to_creator) { struct subscriber *s = lookup_subscriber_id(msg->target_sid); if (IS_SUBSCRIBED(s)) { // calculate the position of the payload void *payload_ptr = (void *) ((uint8_t *) packetbuf_dataptr() + sizeof(struct scopes_msg_data)); // artificial scope entry mockup.scope_id = msg->scope_id; mockup.super_scope_id = 0; mockup.owner = s; // notify the owner CALLBACK(s, recv(&mockup, payload_ptr, msg->data_len)); } } } } break; default: return; } }