mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	protocol-native: Enable srbchannel
The srbchannel is enabled if protocol version >= 30 and SHM is available. There is also a module parameter srbchannel=false that can be used for disabling the srbchannel. The setup is done in these steps: 1) Server receives authentication (like today) 2) Server sends enable_srbchannel to client 3) Server sends memblock to client 4) Client receives enable_srbchannel 5) Client receives memblock 6) Client sends enable_srbchannel back to server 7) Client switches over 8) Server receives enable_srbchannel and switches over Signed-off-by: David Henningsson <david.henningsson@canonical.com>
This commit is contained in:
		
							parent
							
								
									1827991548
								
							
						
					
					
						commit
						a476371254
					
				
					 3 changed files with 81 additions and 1 deletions
				
			
		| 
						 | 
					@ -120,14 +120,17 @@
 | 
				
			||||||
#  endif
 | 
					#  endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#  if defined(HAVE_CREDS) && !defined(USE_TCP_SOCKETS)
 | 
					#  if defined(HAVE_CREDS) && !defined(USE_TCP_SOCKETS)
 | 
				
			||||||
#    define MODULE_ARGUMENTS MODULE_ARGUMENTS_COMMON "auth-group", "auth-group-enable",
 | 
					#    define MODULE_ARGUMENTS MODULE_ARGUMENTS_COMMON "auth-group", "auth-group-enable", "srbchannel",
 | 
				
			||||||
#    define AUTH_USAGE "auth-group=<system group to allow access> auth-group-enable=<enable auth by UNIX group?> "
 | 
					#    define AUTH_USAGE "auth-group=<system group to allow access> auth-group-enable=<enable auth by UNIX group?> "
 | 
				
			||||||
 | 
					#    define SRB_USAGE "srbchannel=<enable shared ringbuffer communication channel?> "
 | 
				
			||||||
#  elif defined(USE_TCP_SOCKETS)
 | 
					#  elif defined(USE_TCP_SOCKETS)
 | 
				
			||||||
#    define MODULE_ARGUMENTS MODULE_ARGUMENTS_COMMON "auth-ip-acl",
 | 
					#    define MODULE_ARGUMENTS MODULE_ARGUMENTS_COMMON "auth-ip-acl",
 | 
				
			||||||
#    define AUTH_USAGE "auth-ip-acl=<IP address ACL to allow access> "
 | 
					#    define AUTH_USAGE "auth-ip-acl=<IP address ACL to allow access> "
 | 
				
			||||||
 | 
					#    define SRB_USAGE
 | 
				
			||||||
#  else
 | 
					#  else
 | 
				
			||||||
#    define MODULE_ARGUMENTS MODULE_ARGUMENTS_COMMON
 | 
					#    define MODULE_ARGUMENTS MODULE_ARGUMENTS_COMMON
 | 
				
			||||||
#    define AUTH_USAGE
 | 
					#    define AUTH_USAGE
 | 
				
			||||||
 | 
					#    define SRB_USAGE
 | 
				
			||||||
#    endif
 | 
					#    endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  PA_MODULE_DESCRIPTION("Native protocol "SOCKET_DESCRIPTION);
 | 
					  PA_MODULE_DESCRIPTION("Native protocol "SOCKET_DESCRIPTION);
 | 
				
			||||||
| 
						 | 
					@ -135,6 +138,7 @@
 | 
				
			||||||
                  "auth-cookie=<path to cookie file> "
 | 
					                  "auth-cookie=<path to cookie file> "
 | 
				
			||||||
                  "auth-cookie-enabled=<enable cookie authentication?> "
 | 
					                  "auth-cookie-enabled=<enable cookie authentication?> "
 | 
				
			||||||
                  AUTH_USAGE
 | 
					                  AUTH_USAGE
 | 
				
			||||||
 | 
					                  SRB_USAGE
 | 
				
			||||||
                  SOCKET_USAGE);
 | 
					                  SOCKET_USAGE);
 | 
				
			||||||
#elif defined(USE_PROTOCOL_ESOUND)
 | 
					#elif defined(USE_PROTOCOL_ESOUND)
 | 
				
			||||||
#  include <pulsecore/protocol-esound.h>
 | 
					#  include <pulsecore/protocol-esound.h>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -181,6 +181,7 @@ struct pa_native_connection {
 | 
				
			||||||
    uint32_t rrobin_index;
 | 
					    uint32_t rrobin_index;
 | 
				
			||||||
    pa_subscription *subscription;
 | 
					    pa_subscription *subscription;
 | 
				
			||||||
    pa_time_event *auth_timeout_event;
 | 
					    pa_time_event *auth_timeout_event;
 | 
				
			||||||
 | 
					    pa_srbchannel *srbpending;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PA_NATIVE_CONNECTION(o) (pa_native_connection_cast(o))
 | 
					#define PA_NATIVE_CONNECTION(o) (pa_native_connection_cast(o))
 | 
				
			||||||
| 
						 | 
					@ -294,6 +295,7 @@ static void command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag,
 | 
				
			||||||
static void command_set_card_profile(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
 | 
					static void command_set_card_profile(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
 | 
				
			||||||
static void command_set_sink_or_source_port(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
 | 
					static void command_set_sink_or_source_port(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
 | 
				
			||||||
static void command_set_port_latency_offset(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
 | 
					static void command_set_port_latency_offset(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
 | 
				
			||||||
 | 
					static void command_enable_srbchannel(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
 | 
					static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
 | 
				
			||||||
    [PA_COMMAND_ERROR] = NULL,
 | 
					    [PA_COMMAND_ERROR] = NULL,
 | 
				
			||||||
| 
						 | 
					@ -397,6 +399,8 @@ static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [PA_COMMAND_SET_PORT_LATENCY_OFFSET] = command_set_port_latency_offset,
 | 
					    [PA_COMMAND_SET_PORT_LATENCY_OFFSET] = command_set_port_latency_offset,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [PA_COMMAND_ENABLE_SRBCHANNEL] = command_enable_srbchannel,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [PA_COMMAND_EXTENSION] = command_extension
 | 
					    [PA_COMMAND_EXTENSION] = command_extension
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1327,6 +1331,9 @@ static void native_connection_unlink(pa_native_connection *c) {
 | 
				
			||||||
    if (c->options)
 | 
					    if (c->options)
 | 
				
			||||||
        pa_native_options_unref(c->options);
 | 
					        pa_native_options_unref(c->options);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (c->srbpending)
 | 
				
			||||||
 | 
					        pa_srbchannel_free(c->srbpending);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while ((r = pa_idxset_first(c->record_streams, NULL)))
 | 
					    while ((r = pa_idxset_first(c->record_streams, NULL)))
 | 
				
			||||||
        record_stream_unlink(r);
 | 
					        record_stream_unlink(r);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2578,6 +2585,65 @@ static void command_exit(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta
 | 
				
			||||||
    pa_pstream_send_simple_ack(c->pstream, tag); /* nonsense */
 | 
					    pa_pstream_send_simple_ack(c->pstream, tag); /* nonsense */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void setup_srbchannel(pa_native_connection *c) {
 | 
				
			||||||
 | 
					    pa_srbchannel_template srbt;
 | 
				
			||||||
 | 
					    pa_srbchannel *srb;
 | 
				
			||||||
 | 
					    pa_memchunk mc;
 | 
				
			||||||
 | 
					    pa_tagstruct *t;
 | 
				
			||||||
 | 
					    int fdlist[2];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!c->options->srbchannel) {
 | 
				
			||||||
 | 
					        pa_log_debug("Disabling srbchannel, reason: Disabled by module parameter");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (c->version < 30) {
 | 
				
			||||||
 | 
					        pa_log_debug("Disabling srbchannel, reason: Protocol too old");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!pa_pstream_get_shm(c->pstream)) {
 | 
				
			||||||
 | 
					        pa_log_debug("Disabling srbchannel, reason: No SHM support");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!c->protocol->core->rw_mempool) {
 | 
				
			||||||
 | 
					        pa_log_debug("Disabling srbchannel, reason: No rw memory pool");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pa_log_debug("Enabling srbchannel...");
 | 
				
			||||||
 | 
					    srb = pa_srbchannel_new(c->protocol->core->mainloop, c->protocol->core->rw_mempool);
 | 
				
			||||||
 | 
					    pa_srbchannel_export(srb, &srbt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Send enable command to client */
 | 
				
			||||||
 | 
					    t = pa_tagstruct_new(NULL, 0);
 | 
				
			||||||
 | 
					    pa_tagstruct_putu32(t, PA_COMMAND_ENABLE_SRBCHANNEL);
 | 
				
			||||||
 | 
					    pa_tagstruct_putu32(t, (size_t) srb); /* tag */
 | 
				
			||||||
 | 
					    fdlist[0] = srbt.readfd;
 | 
				
			||||||
 | 
					    fdlist[1] = srbt.writefd;
 | 
				
			||||||
 | 
					    pa_pstream_send_tagstruct_with_fds(c->pstream, t, 2, fdlist);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Send ringbuffer memblock to client */
 | 
				
			||||||
 | 
					    mc.memblock = srbt.memblock;
 | 
				
			||||||
 | 
					    mc.index = 0;
 | 
				
			||||||
 | 
					    mc.length = pa_memblock_get_length(srbt.memblock);
 | 
				
			||||||
 | 
					    pa_pstream_send_memblock(c->pstream, 0, 0, 0, &mc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    c->srbpending = srb;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void command_enable_srbchannel(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
 | 
				
			||||||
 | 
					    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (tag != (uint32_t) (size_t) c->srbpending)
 | 
				
			||||||
 | 
					        protocol_error(c);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pa_log_debug("Client enabled srbchannel.");
 | 
				
			||||||
 | 
					    pa_pstream_set_srbchannel(c->pstream, c->srbpending);
 | 
				
			||||||
 | 
					    c->srbpending = NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
 | 
					static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
 | 
				
			||||||
    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
 | 
					    pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
 | 
				
			||||||
    const void*cookie;
 | 
					    const void*cookie;
 | 
				
			||||||
| 
						 | 
					@ -2709,6 +2775,8 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
    pa_pstream_send_tagstruct(c->pstream, reply);
 | 
					    pa_pstream_send_tagstruct(c->pstream, reply);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    setup_srbchannel(c);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void command_set_client_name(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
 | 
					static void command_set_client_name(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
 | 
				
			||||||
| 
						 | 
					@ -5017,6 +5085,7 @@ void pa_native_protocol_connect(pa_native_protocol *p, pa_iochannel *io, pa_nati
 | 
				
			||||||
    c->protocol = p;
 | 
					    c->protocol = p;
 | 
				
			||||||
    c->options = pa_native_options_ref(o);
 | 
					    c->options = pa_native_options_ref(o);
 | 
				
			||||||
    c->authorized = false;
 | 
					    c->authorized = false;
 | 
				
			||||||
 | 
					    c->srbpending = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (o->auth_anonymous) {
 | 
					    if (o->auth_anonymous) {
 | 
				
			||||||
        pa_log_info("Client authenticated anonymously.");
 | 
					        pa_log_info("Client authenticated anonymously.");
 | 
				
			||||||
| 
						 | 
					@ -5247,6 +5316,12 @@ int pa_native_options_parse(pa_native_options *o, pa_core *c, pa_modargs *ma) {
 | 
				
			||||||
    pa_assert(PA_REFCNT_VALUE(o) >= 1);
 | 
					    pa_assert(PA_REFCNT_VALUE(o) >= 1);
 | 
				
			||||||
    pa_assert(ma);
 | 
					    pa_assert(ma);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    o->srbchannel = true;
 | 
				
			||||||
 | 
					    if (pa_modargs_get_value_boolean(ma, "srbchannel", &o->srbchannel) < 0) {
 | 
				
			||||||
 | 
					        pa_log("srbchannel= expects a boolean argument.");
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (pa_modargs_get_value_boolean(ma, "auth-anonymous", &o->auth_anonymous) < 0) {
 | 
					    if (pa_modargs_get_value_boolean(ma, "auth-anonymous", &o->auth_anonymous) < 0) {
 | 
				
			||||||
        pa_log("auth-anonymous= expects a boolean argument.");
 | 
					        pa_log("auth-anonymous= expects a boolean argument.");
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,6 +44,7 @@ typedef struct pa_native_options {
 | 
				
			||||||
    pa_module *module;
 | 
					    pa_module *module;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool auth_anonymous;
 | 
					    bool auth_anonymous;
 | 
				
			||||||
 | 
					    bool srbchannel;
 | 
				
			||||||
    char *auth_group;
 | 
					    char *auth_group;
 | 
				
			||||||
    pa_ip_acl *auth_ip_acl;
 | 
					    pa_ip_acl *auth_ip_acl;
 | 
				
			||||||
    pa_auth_cookie *auth_cookie;
 | 
					    pa_auth_cookie *auth_cookie;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue