diff options
| author | Lennart Poettering <lennart@poettering.net> | 2004-07-15 00:16:27 +0000 | 
|---|---|---|
| committer | Lennart Poettering <lennart@poettering.net> | 2004-07-15 00:16:27 +0000 | 
| commit | 1416fef19796fa5372e6ed02cfd18574a040255f (patch) | |
| tree | bf37d45b832d23105de2f6849714742294090529 /src | |
| parent | e83b7106ac1c008d1fa077c4bbb68423a46e604c (diff) | |
implement client side TCP support
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@67 fefdeb5f-60dc-0310-8127-8f9354f1896f
Diffstat (limited to 'src')
| -rw-r--r-- | src/cli-command.c | 5 | ||||
| -rw-r--r-- | src/polyp.c | 65 | ||||
| -rw-r--r-- | src/protocol-native-spec.h | 1 | ||||
| -rw-r--r-- | src/socket-client.c | 31 | ||||
| -rw-r--r-- | src/socket-client.h | 1 | ||||
| -rw-r--r-- | src/todo | 7 | 
6 files changed, 100 insertions, 10 deletions
diff --git a/src/cli-command.c b/src/cli-command.c index 06e0eb30..bf3ab0c4 100644 --- a/src/cli-command.c +++ b/src/cli-command.c @@ -193,9 +193,10 @@ static int pa_cli_command_load(struct pa_core *c, struct pa_tokenizer *t, struct          return -1;      } -    if (*verbose) +    if (*verbose) {          snprintf(txt, sizeof(txt), "Module successfully loaded, index: %u.\n", m->index); -    pa_strbuf_puts(buf, txt); +        pa_strbuf_puts(buf, txt); +    }      return 0;  } diff --git a/src/polyp.c b/src/polyp.c index fde0c68b..75187d79 100644 --- a/src/polyp.c +++ b/src/polyp.c @@ -2,6 +2,9 @@  #include <assert.h>  #include <stdlib.h>  #include <string.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h>  #include "polyp.h"  #include "protocol-native-spec.h" @@ -21,6 +24,7 @@  #define DEFAULT_TIMEOUT (5*60)  #define DEFAULT_SERVER "/tmp/polypaudio/native" +#define DEFAULT_PORT "4713"  struct pa_context {      char *name; @@ -284,7 +288,7 @@ static void on_connection(struct pa_socket_client *client, struct pa_iochannel*i      struct pa_context *c = userdata;      struct pa_tagstruct *t;      uint32_t tag; -    assert(client && io && c && c->state == CONTEXT_CONNECTING); +    assert(client && c && c->state == CONTEXT_CONNECTING);      pa_socket_client_free(client);      c->client = NULL; @@ -318,6 +322,36 @@ static void on_connection(struct pa_socket_client *client, struct pa_iochannel*i      c->state = CONTEXT_AUTHORIZING;  } +static struct sockaddr *resolve_server(const char *server, size_t *len) { +    struct sockaddr *sa; +    struct addrinfo hints, *result = NULL; +    char *port; +    assert(server && len); + +    if ((port = strrchr(server, ':'))) +        port++; +    if (!port) +        port = DEFAULT_PORT; + +    memset(&hints, 0, sizeof(hints)); +    hints.ai_family = PF_UNSPEC; +    hints.ai_socktype = SOCK_STREAM; +    hints.ai_protocol = 0; + +    if (getaddrinfo(server, port, &hints, &result) != 0) +        return NULL; +    assert(result); +     +    sa = malloc(*len = result->ai_addrlen); +    assert(sa); +    memcpy(sa, result->ai_addr, *len); + +    freeaddrinfo(result); +     +    return sa; +     +} +  int pa_context_connect(struct pa_context *c, const char *server, void (*complete) (struct pa_context*c, int success, void *userdata), void *userdata) {      assert(c && c->state == CONTEXT_UNCONNECTED); @@ -326,10 +360,33 @@ int pa_context_connect(struct pa_context *c, const char *server, void (*complete          return -1;      } +    if (!server) +        if (!(server = getenv("POLYP_SERVER"))) +            server = DEFAULT_SERVER; +      assert(!c->client); -    if (!(c->client = pa_socket_client_new_unix(c->mainloop, server ? server : DEFAULT_SERVER))) { -        c->error = PA_ERROR_CONNECTIONREFUSED; -        return -1; +     +    if (*server == '/') { +        if (!(c->client = pa_socket_client_new_unix(c->mainloop, server))) { +            c->error = PA_ERROR_CONNECTIONREFUSED; +            return -1; +        } +    } else { +        struct sockaddr* sa; +        size_t sa_len; + +        if (!(sa = resolve_server(server, &sa_len))) { +            c->error = PA_ERROR_INVALIDSERVER; +            return -1; +        } + +        c->client = pa_socket_client_new_sockaddr(c->mainloop, sa, sa_len); +        free(sa); + +        if (!c->client) { +            c->error = PA_ERROR_CONNECTIONREFUSED; +            return -1; +        }      }      c->connect_complete_callback = complete; diff --git a/src/protocol-native-spec.h b/src/protocol-native-spec.h index 5e67fe74..78dc06c2 100644 --- a/src/protocol-native-spec.h +++ b/src/protocol-native-spec.h @@ -35,6 +35,7 @@ enum {      PA_ERROR_INTERNAL,      PA_ERROR_CONNECTIONTERMINATED,      PA_ERROR_KILLED, +    PA_ERROR_INVALIDSERVER,      PA_ERROR_MAX  }; diff --git a/src/socket-client.c b/src/socket-client.c index 8b2bd384..b1e609ab 100644 --- a/src/socket-client.c +++ b/src/socket-client.c @@ -80,7 +80,7 @@ static void connect_fixed_cb(struct pa_mainloop_api *m, void *id, void *userdata  static void connect_io_cb(struct pa_mainloop_api*m, void *id, int fd, enum pa_mainloop_api_io_events events, void *userdata) {      struct pa_socket_client *c = userdata; -    assert(m && c && c->io_source == id && fd >= 0 && events == PA_MAINLOOP_API_IO_EVENT_OUTPUT); +    assert(m && c && c->io_source == id && fd >= 0);      m->cancel_io(m, c->io_source);      c->io_source = NULL;      do_call(c); @@ -93,7 +93,7 @@ static int do_connect(struct pa_socket_client *c, const struct sockaddr *sa, soc      pa_make_nonblock_fd(c->fd);      if ((r = connect(c->fd, sa, len)) < 0) { -        if (r != EINPROGRESS) { +        if (errno != EINPROGRESS) {              fprintf(stderr, "connect(): %s\n", strerror(errno));              return -1;          } @@ -165,7 +165,34 @@ fail:      pa_socket_client_free(c);      return NULL;  } + +struct pa_socket_client* pa_socket_client_new_sockaddr(struct pa_mainloop_api *m, const struct sockaddr *sa, size_t salen) { +    struct pa_socket_client *c; +    assert(m && sa); +    c = pa_socket_client_new(m); +    assert(c); + +    if ((c->fd = socket(sa->sa_family, SOCK_STREAM, 0)) < 0) { +        fprintf(stderr, "socket(): %s\n", strerror(errno)); +        goto fail; +    } + +    if (sa->sa_family == AF_INET) +        pa_socket_tcp_low_delay(c->fd); +    else +        pa_socket_low_delay(c->fd); + +    if (do_connect(c, sa, salen) < 0) +        goto fail; +    return c; + +fail: +    pa_socket_client_free(c); +    return NULL; +     +} +  void pa_socket_client_free(struct pa_socket_client *c) {      assert(c && c->mainloop);      if (c->io_source) diff --git a/src/socket-client.h b/src/socket-client.h index 046cc3a5..85753788 100644 --- a/src/socket-client.h +++ b/src/socket-client.h @@ -11,6 +11,7 @@ struct pa_socket_client;  struct pa_socket_client* pa_socket_client_new_ipv4(struct pa_mainloop_api *m, uint32_t address, uint16_t port);  struct pa_socket_client* pa_socket_client_new_unix(struct pa_mainloop_api *m, const char *filename); +struct pa_socket_client* pa_socket_client_new_sockaddr(struct pa_mainloop_api *m, const struct sockaddr *sa, size_t salen);  void pa_socket_client_free(struct pa_socket_client *c); @@ -1,8 +1,10 @@ +- modargs memory leak + +- clean secure directory handling (with username) +  - native library/protocol:         more functions (esp. latency) -- daemonizing -  - prefix modules/libraries with pa_  - xmms+esound latency testing @@ -25,6 +27,7 @@  - doxygen  - make mcalign merge chunks  - modinfo +- daemonizing  drivers:  - libao  | 
