Beispiel #1
0
int32_t _shutdowns_direct( uint8_t index, struct session_manager * manager, struct sidlist * ids )
{
    uint32_t i = 0;
    int32_t count = 0;

    for ( i = 0; i < sidlist_count(ids); ++i )
    {
        sid_t id = sidlist_get(ids, i);

        if ( SID_INDEX(id) != index )
        {
            continue;
        }

        struct session * session = session_manager_get( manager, id );
        if ( session == NULL )
        {
            continue;
        }

        // 直接终止
        ++count;
        session_close( session );
        session_shutdown( session );
    }

    sidlist_destroy( ids );

    return count;
}
Beispiel #2
0
int
recv_init(struct nbr *nbr, char *buf, u_int16_t len)
{
	struct ldp_msg		init;
	struct sess_prms_tlv	sess;

	log_debug("recv_init: neighbor ID %s", inet_ntoa(nbr->id));

	bcopy(buf, &init, sizeof(init));

	buf += sizeof(struct ldp_msg);
	len -= sizeof(struct ldp_msg);

	if (len < SESS_PRMS_SIZE) {
		session_shutdown(nbr, S_BAD_MSG_LEN, init.msgid, init.type);
		return (-1);
	}
	bcopy(buf, &sess, sizeof(sess));

	if (ntohs(sess.length) != SESS_PRMS_SIZE - TLV_HDR_LEN ||
	    ntohs(sess.length) > len - TLV_HDR_LEN) {
		session_shutdown(nbr, S_BAD_TLV_LEN, init.msgid, init.type);
		return (-1);
	}

	if (ntohs(sess.proto_version) != LDP_VERSION) {
		session_shutdown(nbr, S_BAD_PROTO_VER, init.msgid, init.type);
		return (-1);
	}

	buf += SESS_PRMS_SIZE;
	len -= SESS_PRMS_SIZE;

	/* just ignore all optional TLVs for now */
	if (tlv_decode_opt_init_prms(buf, len) == -1) {
		session_shutdown(nbr, S_BAD_TLV_VAL, init.msgid, init.type);
		return (-1);
	}

	nbr->keepalive = min(leconf->keepalive, ntohs(sess.keepalive_time));

	if (!nbr_pending_idtimer(nbr))
		nbr_fsm(nbr, NBR_EVT_INIT_RCVD);

	return (ntohs(init.length));
}
Beispiel #3
0
int
recv_notification(struct nbr *nbr, char *buf, u_int16_t len)
{
	struct ldp_msg		not;
	struct status_tlv	st;

	log_debug("recv_notification: neighbor ID %s", inet_ntoa(nbr->id));

	bcopy(buf, &not, sizeof(not));

	buf += sizeof(struct ldp_msg);
	len -= sizeof(struct ldp_msg);

	if (len < STATUS_SIZE) {
		session_shutdown(nbr, S_BAD_MSG_LEN, not.msgid, not.type);
		return (-1);
	}
	bcopy(buf, &st, sizeof(st));

	if (ntohs(st.length) > STATUS_SIZE - TLV_HDR_LEN ||
	    ntohs(st.length) > len - TLV_HDR_LEN) {
		session_shutdown(nbr, S_BAD_TLV_LEN, not.msgid, not.type);
		return (-1);
	}

	/* TODO optional parameters: ext status, returned PDU and msg */

	if (st.status_code & htonl(STATUS_FATAL))
		log_warnx("received notification from neighbor %s: %s",
		    inet_ntoa(nbr->id),
		    notification_name(ntohl(st.status_code)));
	else
		log_debug("received non-fatal notification from neighbor "
		    "%s: %s", inet_ntoa(nbr->id),
		    notification_name(ntohl(st.status_code)));

	if (st.status_code & htonl(STATUS_FATAL)) {
		nbr_fsm(nbr, NBR_EVT_CLOSE_SESSION);
		return (-1);
	}
	/* XXX in some cases we should inform the RDE about non-fatal ones */

	return (ntohs(not.length));
}
Beispiel #4
0
int32_t _shutdown_direct( struct session_manager * manager, sid_t id )
{
    struct session * session = session_manager_get( manager, id );

    if ( session == NULL )
    {
        syslog(LOG_WARNING, "%s(SID=%ld) failed, the Session is invalid .", __FUNCTION__,id );
        return -1;
    }

    // 设置会话被逻辑层终止了
    session_close( session );
    return session_shutdown( session );
}
Beispiel #5
0
int
recv_keepalive(struct nbr *nbr, char *buf, u_int16_t len)
{
	struct ldp_msg ka;

	bcopy(buf, &ka, sizeof(ka));

	if (len != LDP_MSG_LEN) {
		session_shutdown(nbr, S_BAD_MSG_LEN, ka.msgid, ka.type);
		return (-1);
	}

	if (nbr->state != NBR_STA_OPER)
		nbr_fsm(nbr, NBR_EVT_KEEPALIVE_RCVD);
	else
		nbr_fsm(nbr, NBR_EVT_PDU_RCVD);

	return (ntohs(ka.length));
}
Beispiel #6
0
static void
initiate_shutdown (GsmSession *session)
{
  GSList *cl;

  session->phase = GSM_SESSION_PHASE_SHUTDOWN;

  if (session->clients == NULL)
    session_shutdown (session);

  for (cl = session->clients; cl; cl = cl->next)
    {
      GsmClient *client = GSM_CLIENT (cl->data);

      session->shutdown_clients =
	g_slist_prepend (session->shutdown_clients, client);

      gsm_client_save_yourself (client, FALSE);
    }
}
Beispiel #7
0
static void
client_save_yourself_done (GsmClient *client, gpointer data)
{
  GsmSession *session = data;

  session->shutdown_clients =
    g_slist_remove (session->shutdown_clients, client);
  session->interact_clients =
    g_slist_remove (session->interact_clients, client);
  session->phase2_clients =
    g_slist_remove (session->phase2_clients, client);

  if (session->phase == GSM_SESSION_PHASE_SHUTDOWN &&
      !session->shutdown_clients)
    {
      if (session->phase2_clients)
	session_shutdown_phase2 (session);
      else
	session_shutdown (session);
    }
}
Beispiel #8
0
static void
_shutdown(void)
{
    if (prefs_get_boolean(PREF_WINTITLE_SHOW)) {
        if (prefs_get_boolean(PREF_WINTITLE_GOODBYE)) {
            ui_goodbye_title();
        } else {
            ui_clear_win_title();
        }
    }

    jabber_conn_status_t conn_status = connection_get_status();
    if (conn_status == JABBER_CONNECTED) {
        cl_ev_disconnect();
    }
#ifdef HAVE_GTK
    tray_shutdown();
#endif
    session_shutdown();
    plugins_on_shutdown();
    muc_close();
    caps_close();
#ifdef HAVE_LIBOTR
    otr_shutdown();
#endif
#ifdef HAVE_LIBGPGME
    p_gpg_close();
#endif
    chat_log_close();
    theme_close();
    accounts_close();
    tlscerts_close();
    log_stderr_close();
    log_close();
    plugins_shutdown();
    cmd_uninit();
    ui_close();
    prefs_close();
}
Beispiel #9
0
static int on_session(session *s, void *param)
{
	if (session_on_connect(s))
	{
		printf("CONNECTED\n");
		return 1;
	}

	if (session_on_disconnect(s))
	{
		printf("DISCONNECTED\n");
		return 0;
	}

	char *msg;

	if (!session_readmsg(s, &msg))         // read the echo
		return 0;

	if (!g_quiet) printf("DATA: %s", msg);

	int count = session_get_udata_int(s);

	if (count++ == g_loops)
	{
		session_shutdown(s);
		return 0;
	}

	session_set_udata_int(s, count);

	if (session_writemsg(s, hello) <= 0)
	{
		printf("write: %s\n", strerror(errno));
		return 0;
	}

	return 1;
}
Beispiel #10
0
static void session_cleanup(struct event_session *session)
{
	session_shutdown(session);
	ao2_cleanup(session);
}
Beispiel #11
0
int
recv_address(struct nbr *nbr, char *buf, u_int16_t len)
{
	struct ldp_msg		addr;
	struct address_list_tlv	alt;
	enum imsg_type		type;

	if (nbr->state != NBR_STA_OPER) {
		log_debug("recv_address: neighbor ID %s not operational",
		    inet_ntoa(nbr->id));
		return (-1);
	}

	bcopy(buf, &addr, sizeof(addr));
	log_debug("recv_address: neighbor ID %s%s", inet_ntoa(nbr->id),
	    ntohs(addr.type) == MSG_TYPE_ADDR ? "" : " address withdraw");
	if (ntohs(addr.type) == MSG_TYPE_ADDR)
		type = IMSG_ADDRESS_ADD;
	else
		type = IMSG_ADDRESS_DEL;

	buf += sizeof(struct ldp_msg);
	len -= sizeof(struct ldp_msg);

	if (len < sizeof(alt)) {
		session_shutdown(nbr, S_BAD_MSG_LEN, addr.msgid, addr.type);
		return (-1);
	}

	bcopy(buf, &alt, sizeof(alt));

	if (ntohs(alt.length) != len - TLV_HDR_LEN) {
		session_shutdown(nbr, S_BAD_TLV_LEN, addr.msgid, addr.type);
		return (-1);
	}

	if (ntohs(alt.type) != TLV_TYPE_ADDRLIST) {
		session_shutdown(nbr, S_UNKNOWN_TLV, addr.msgid, addr.type);
		return (-1);
	}

	/* For now we only support IPv4 */
	if (alt.family != htons(ADDR_IPV4)) {
		send_notification_nbr(nbr, S_UNSUP_ADDR, addr.msgid, addr.type);
		return (-1);
	}

	buf += sizeof(alt);
	len -= sizeof(alt);

	while (len >= sizeof(struct in_addr)) {
		ldpe_imsg_compose_lde(type, nbr->peerid, 0,
		    buf, sizeof(struct in_addr));

		buf += sizeof(struct in_addr);
		len -= sizeof(struct in_addr);
	}

	if (len != 0) {
		session_shutdown(nbr, S_BAD_TLV_LEN, addr.msgid, addr.type);
		return (-1);
	}

	return (ntohs(addr.length));
}
Beispiel #12
0
int
recv_notification(struct nbr *nbr, char *buf, uint16_t len)
{
	struct ldp_msg		msg;
	struct status_tlv	st;
	struct notify_msg	nm;
	int			tlen;

	memcpy(&msg, buf, sizeof(msg));
	buf += LDP_MSG_SIZE;
	len -= LDP_MSG_SIZE;

	if (len < STATUS_SIZE) {
		session_shutdown(nbr, S_BAD_MSG_LEN, msg.id, msg.type);
		return (-1);
	}
	memcpy(&st, buf, sizeof(st));

	if (ntohs(st.length) > STATUS_SIZE - TLV_HDR_SIZE ||
	    ntohs(st.length) > len - TLV_HDR_SIZE) {
		session_shutdown(nbr, S_BAD_TLV_LEN, msg.id, msg.type);
		return (-1);
	}
	buf += STATUS_SIZE;
	len -= STATUS_SIZE;

	memset(&nm, 0, sizeof(nm));
	nm.status_code = ntohl(st.status_code);

	/* Optional Parameters */
	while (len > 0) {
		struct tlv 	tlv;
		uint16_t	tlv_len;

		if (len < sizeof(tlv)) {
			session_shutdown(nbr, S_BAD_TLV_LEN, msg.id, msg.type);
			return (-1);
		}

		memcpy(&tlv, buf, TLV_HDR_SIZE);
		tlv_len = ntohs(tlv.length);
		if (tlv_len + TLV_HDR_SIZE > len) {
			session_shutdown(nbr, S_BAD_TLV_LEN, msg.id, msg.type);
			return (-1);
		}
		buf += TLV_HDR_SIZE;
		len -= TLV_HDR_SIZE;

		switch (ntohs(tlv.type)) {
		case TLV_TYPE_EXTSTATUS:
		case TLV_TYPE_RETURNEDPDU:
		case TLV_TYPE_RETURNEDMSG:
			/* TODO is there any use for this? */
			break;
		case TLV_TYPE_PW_STATUS:
			if (tlv_len != 4) {
				session_shutdown(nbr, S_BAD_TLV_LEN,
				    msg.id, msg.type);
				return (-1);
			}

			nm.pw_status = ntohl(*(uint32_t *)buf);
			nm.flags |= F_NOTIF_PW_STATUS;
			break;
		case TLV_TYPE_FEC:
			if ((tlen = tlv_decode_fec_elm(nbr, &msg, buf,
			    tlv_len, &nm.fec)) == -1)
				return (-1);
			/* allow only one fec element */
			if (tlen != tlv_len) {
				session_shutdown(nbr, S_BAD_TLV_VAL,
				    msg.id, msg.type);
				return (-1);
			}
			nm.flags |= F_NOTIF_FEC;
			break;
		default:
			if (!(ntohs(tlv.type) & UNKNOWN_FLAG))
				send_notification_nbr(nbr, S_UNKNOWN_TLV,
				    msg.id, msg.type);
			/* ignore unknown tlv */
			break;
		}
		buf += tlv_len;
		len -= tlv_len;
	}

	if (nm.status_code == S_PW_STATUS) {
		if (!(nm.flags & (F_NOTIF_PW_STATUS|F_NOTIF_FEC))) {
			send_notification_nbr(nbr, S_MISS_MSG,
			    msg.id, msg.type);
			return (-1);
		}

		switch (nm.fec.type) {
		case MAP_TYPE_PWID:
			break;
		default:
			send_notification_nbr(nbr, S_BAD_TLV_VAL,
			    msg.id, msg.type);
			return (-1);
		}
	}

	if (st.status_code & htonl(STATUS_FATAL))
		log_warnx("received notification from lsr-id %s: %s",
		    inet_ntoa(nbr->id),
		    status_code_name(ntohl(st.status_code)));
	else
		log_debug("received non-fatal notification from lsr-id "
		    "%s: %s", inet_ntoa(nbr->id),
		    status_code_name(ntohl(st.status_code)));

	if (st.status_code & htonl(STATUS_FATAL)) {
		if (nbr->state == NBR_STA_OPENSENT)
			nbr_start_idtimer(nbr);

		nbr_fsm(nbr, NBR_EVT_CLOSE_SESSION);
		return (-1);
	}

	if (nm.status_code == S_PW_STATUS)
		ldpe_imsg_compose_lde(IMSG_NOTIFICATION, nbr->peerid, 0,
		    &nm, sizeof(nm));

	return (0);
}
Beispiel #13
0
static void owner_disconnected(DBusConnection *connection, void *user_data)
{
	struct session_data *session = user_data;

	session_shutdown(session);
}