+static int c_rtp_cancel(struct conn *c,
+ char attribute((unused)) **vec,
+ int attribute((unused)) nvec) {
+ if(!c->rtp_requested) {
+ sink_writes(ev_writer_sink(c->w), "550 No active RTP stream\n");
+ return 1;
+ }
+ rtp_request_cancel(&c->rtp_destination);
+ c->rtp_requested = 0;
+ sink_writes(ev_writer_sink(c->w), "250 Cancelled RTP stream\n");
+ return 1;
+}
+
+static int c_rtp_request(struct conn *c,
+ char **vec,
+ int attribute((unused)) nvec) {
+ static const struct addrinfo hints = {
+ .ai_family = AF_UNSPEC,
+ .ai_socktype = SOCK_DGRAM,
+ .ai_protocol = IPPROTO_UDP,
+ .ai_flags = AI_NUMERICHOST|AI_NUMERICSERV,
+ };
+ struct addrinfo *res;
+ int rc = getaddrinfo(vec[0], vec[1], &hints, &res);
+ if(rc) {
+ disorder_error(0, "%s port %s: %s",
+ vec[0], vec[1], gai_strerror(rc));
+ sink_writes(ev_writer_sink(c->w), "550 Invalid address\n");
+ return 1;
+ }
+ disorder_info("%s requested RTP stream to %s %s", c->who, vec[0], vec[1]);
+ /* TODO might be useful to tighten this up to restrict clients to targetting
+ * themselves only */
+ if(c->rtp_requested) {
+ rtp_request_cancel(&c->rtp_destination);
+ c->rtp_requested = 0;
+ }
+ memcpy(&c->rtp_destination, res->ai_addr, res->ai_addrlen);
+ freeaddrinfo(res);
+ rtp_request(&c->rtp_destination);
+ c->rtp_requested = 1;
+ sink_writes(ev_writer_sink(c->w), "250 Initiated RTP stream\n");
+ // TODO teardown on connection close
+ return 1;
+}
+