Subscription time limit
Add expiration time to subscriptions; they need to be renewed before they expiry. This way, the subscription automatically times out when phc2sys is killed. Signed-off-by: Jiri Benc <jbenc@redhat.com>
This commit is contained in:
		
							parent
							
								
									5104e3e56b
								
							
						
					
					
						commit
						0e8efe418c
					
				
							
								
								
									
										38
									
								
								clock.c
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								clock.c
									
									
									
									
									
								
							| @ -66,6 +66,7 @@ struct clock_subscriber { | |||||||
| 	struct PortIdentity targetPortIdentity; | 	struct PortIdentity targetPortIdentity; | ||||||
| 	struct address addr; | 	struct address addr; | ||||||
| 	UInteger16 sequenceId; | 	UInteger16 sequenceId; | ||||||
|  | 	time_t expiration; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct clock { | struct clock { | ||||||
| @ -134,10 +135,11 @@ static void remove_subscriber(struct clock_subscriber *s) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void clock_update_subscription(struct clock *c, struct ptp_message *req, | static void clock_update_subscription(struct clock *c, struct ptp_message *req, | ||||||
| 				      uint8_t *bitmask) | 				      uint8_t *bitmask, uint16_t duration) | ||||||
| { | { | ||||||
| 	struct clock_subscriber *s; | 	struct clock_subscriber *s; | ||||||
| 	int i, remove = 1; | 	int i, remove = 1; | ||||||
|  | 	struct timespec now; | ||||||
| 
 | 
 | ||||||
| 	for (i = 0; i < EVENT_BITMASK_CNT; i++) { | 	for (i = 0; i < EVENT_BITMASK_CNT; i++) { | ||||||
| 		if (bitmask[i]) { | 		if (bitmask[i]) { | ||||||
| @ -154,6 +156,8 @@ static void clock_update_subscription(struct clock *c, struct ptp_message *req, | |||||||
| 			if (!remove) { | 			if (!remove) { | ||||||
| 				s->addr = req->address; | 				s->addr = req->address; | ||||||
| 				memcpy(s->events, bitmask, EVENT_BITMASK_CNT); | 				memcpy(s->events, bitmask, EVENT_BITMASK_CNT); | ||||||
|  | 				clock_gettime(CLOCK_MONOTONIC, &now); | ||||||
|  | 				s->expiration = now.tv_sec + duration; | ||||||
| 			} else { | 			} else { | ||||||
| 				remove_subscriber(s); | 				remove_subscriber(s); | ||||||
| 			} | 			} | ||||||
| @ -171,24 +175,33 @@ static void clock_update_subscription(struct clock *c, struct ptp_message *req, | |||||||
| 	s->targetPortIdentity = req->header.sourcePortIdentity; | 	s->targetPortIdentity = req->header.sourcePortIdentity; | ||||||
| 	s->addr = req->address; | 	s->addr = req->address; | ||||||
| 	memcpy(s->events, bitmask, EVENT_BITMASK_CNT); | 	memcpy(s->events, bitmask, EVENT_BITMASK_CNT); | ||||||
|  | 	clock_gettime(CLOCK_MONOTONIC, &now); | ||||||
|  | 	s->expiration = now.tv_sec + duration; | ||||||
| 	s->sequenceId = 0; | 	s->sequenceId = 0; | ||||||
| 	LIST_INSERT_HEAD(&c->subscribers, s, list); | 	LIST_INSERT_HEAD(&c->subscribers, s, list); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void clock_get_subscription(struct clock *c, struct ptp_message *req, | static void clock_get_subscription(struct clock *c, struct ptp_message *req, | ||||||
| 				   uint8_t *bitmask) | 				   uint8_t *bitmask, uint16_t *duration) | ||||||
| { | { | ||||||
| 	struct clock_subscriber *s; | 	struct clock_subscriber *s; | ||||||
|  | 	struct timespec now; | ||||||
| 
 | 
 | ||||||
| 	LIST_FOREACH(s, &c->subscribers, list) { | 	LIST_FOREACH(s, &c->subscribers, list) { | ||||||
| 		if (!memcmp(&s->targetPortIdentity, &req->header.sourcePortIdentity, | 		if (!memcmp(&s->targetPortIdentity, &req->header.sourcePortIdentity, | ||||||
| 			    sizeof(struct PortIdentity))) { | 			    sizeof(struct PortIdentity))) { | ||||||
| 			memcpy(bitmask, s->events, EVENT_BITMASK_CNT); | 			memcpy(bitmask, s->events, EVENT_BITMASK_CNT); | ||||||
|  | 			clock_gettime(CLOCK_MONOTONIC, &now); | ||||||
|  | 			if (s->expiration < now.tv_sec) | ||||||
|  | 				*duration = 0; | ||||||
|  | 			else | ||||||
|  | 				*duration = s->expiration - now.tv_sec; | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	/* A client without entry means the client has no subscriptions. */ | 	/* A client without entry means the client has no subscriptions. */ | ||||||
| 	memset(bitmask, 0, EVENT_BITMASK_CNT); | 	memset(bitmask, 0, EVENT_BITMASK_CNT); | ||||||
|  | 	*duration = 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void clock_flush_subscriptions(struct clock *c) | static void clock_flush_subscriptions(struct clock *c) | ||||||
| @ -200,6 +213,21 @@ static void clock_flush_subscriptions(struct clock *c) | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void clock_prune_subscriptions(struct clock *c) | ||||||
|  | { | ||||||
|  | 	struct clock_subscriber *s, *tmp; | ||||||
|  | 	struct timespec now; | ||||||
|  | 
 | ||||||
|  | 	clock_gettime(CLOCK_MONOTONIC, &now); | ||||||
|  | 	LIST_FOREACH_SAFE(s, &c->subscribers, list, tmp) { | ||||||
|  | 		if (s->expiration <= now.tv_sec) { | ||||||
|  | 			pr_info("subscriber %s timed out", | ||||||
|  | 				pid2str(&s->targetPortIdentity)); | ||||||
|  | 			remove_subscriber(s); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void clock_send_notification(struct clock *c, struct ptp_message *msg, | void clock_send_notification(struct clock *c, struct ptp_message *msg, | ||||||
| 			     int msglen, enum notification event) | 			     int msglen, enum notification event) | ||||||
| { | { | ||||||
| @ -410,7 +438,7 @@ static int clock_management_get_response(struct clock *c, struct port *p, | |||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
| 		sen = (struct subscribe_events_np *)tlv->data; | 		sen = (struct subscribe_events_np *)tlv->data; | ||||||
| 		clock_get_subscription(c, req, sen->bitmask); | 		clock_get_subscription(c, req, sen->bitmask, &sen->duration); | ||||||
| 		respond = 1; | 		respond = 1; | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
| @ -450,7 +478,8 @@ static int clock_management_set(struct clock *c, struct port *p, | |||||||
| 		break; | 		break; | ||||||
| 	case SUBSCRIBE_EVENTS_NP: | 	case SUBSCRIBE_EVENTS_NP: | ||||||
| 		sen = (struct subscribe_events_np *)tlv->data; | 		sen = (struct subscribe_events_np *)tlv->data; | ||||||
| 		clock_update_subscription(c, req, sen->bitmask); | 		clock_update_subscription(c, req, sen->bitmask, | ||||||
|  | 					  sen->duration); | ||||||
| 		respond = 1; | 		respond = 1; | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
| @ -1103,6 +1132,7 @@ int clock_poll(struct clock *c) | |||||||
| 	if (sde) | 	if (sde) | ||||||
| 		handle_state_decision_event(c); | 		handle_state_decision_event(c); | ||||||
| 
 | 
 | ||||||
|  | 	clock_prune_subscriptions(c); | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										8
									
								
								tlv.c
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								tlv.c
									
									
									
									
									
								
							| @ -62,6 +62,7 @@ static int mgt_post_recv(struct management_tlv *m, uint16_t data_len, | |||||||
| 	struct port_ds_np *pdsnp; | 	struct port_ds_np *pdsnp; | ||||||
| 	struct time_status_np *tsn; | 	struct time_status_np *tsn; | ||||||
| 	struct grandmaster_settings_np *gsn; | 	struct grandmaster_settings_np *gsn; | ||||||
|  | 	struct subscribe_events_np *sen; | ||||||
| 	struct mgmt_clock_description *cd; | 	struct mgmt_clock_description *cd; | ||||||
| 	int extra_len = 0, len; | 	int extra_len = 0, len; | ||||||
| 	uint8_t *buf; | 	uint8_t *buf; | ||||||
| @ -245,6 +246,8 @@ static int mgt_post_recv(struct management_tlv *m, uint16_t data_len, | |||||||
| 	case SUBSCRIBE_EVENTS_NP: | 	case SUBSCRIBE_EVENTS_NP: | ||||||
| 		if (data_len != sizeof(struct subscribe_events_np)) | 		if (data_len != sizeof(struct subscribe_events_np)) | ||||||
| 			goto bad_length; | 			goto bad_length; | ||||||
|  | 		sen = (struct subscribe_events_np *)m->data; | ||||||
|  | 		sen->duration = ntohs(sen->duration); | ||||||
| 		break; | 		break; | ||||||
| 	case SAVE_IN_NON_VOLATILE_STORAGE: | 	case SAVE_IN_NON_VOLATILE_STORAGE: | ||||||
| 	case RESET_NON_VOLATILE_STORAGE: | 	case RESET_NON_VOLATILE_STORAGE: | ||||||
| @ -277,6 +280,7 @@ static void mgt_pre_send(struct management_tlv *m, struct tlv_extra *extra) | |||||||
| 	struct port_ds_np *pdsnp; | 	struct port_ds_np *pdsnp; | ||||||
| 	struct time_status_np *tsn; | 	struct time_status_np *tsn; | ||||||
| 	struct grandmaster_settings_np *gsn; | 	struct grandmaster_settings_np *gsn; | ||||||
|  | 	struct subscribe_events_np *sen; | ||||||
| 	struct mgmt_clock_description *cd; | 	struct mgmt_clock_description *cd; | ||||||
| 	switch (m->id) { | 	switch (m->id) { | ||||||
| 	case CLOCK_DESCRIPTION: | 	case CLOCK_DESCRIPTION: | ||||||
| @ -341,6 +345,10 @@ static void mgt_pre_send(struct management_tlv *m, struct tlv_extra *extra) | |||||||
| 		pdsnp->neighborPropDelayThresh = htonl(pdsnp->neighborPropDelayThresh); | 		pdsnp->neighborPropDelayThresh = htonl(pdsnp->neighborPropDelayThresh); | ||||||
| 		pdsnp->asCapable = htonl(pdsnp->asCapable); | 		pdsnp->asCapable = htonl(pdsnp->asCapable); | ||||||
| 		break; | 		break; | ||||||
|  | 	case SUBSCRIBE_EVENTS_NP: | ||||||
|  | 		sen = (struct subscribe_events_np *)m->data; | ||||||
|  | 		sen->duration = htons(sen->duration); | ||||||
|  | 		break; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user