add support for querying local/remote address
authorFelix Fietkau <nbd@openwrt.org>
Mon, 7 Apr 2014 19:11:58 +0000 (21:11 +0200)
committerFelix Fietkau <nbd@openwrt.org>
Mon, 7 Apr 2014 19:11:58 +0000 (21:11 +0200)
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
uclient-example.c
uclient-http.c
uclient.c
uclient.h

index 2e88b28b871e673b689dc60938b51645ff370fcd..a54aa889d202d5c6d8b9b32e843bf94da0009881 100644 (file)
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
-#include <libubox/blobmsg.h>
+
 #include <unistd.h>
 #include <stdio.h>
 
+#include <libubox/blobmsg.h>
+
 #include "uclient.h"
 
+
 static void example_header_done(struct uclient *cl)
 {
        struct blob_attr *cur;
+       char local[INET6_ADDRSTRLEN], remote[INET6_ADDRSTRLEN];
+       int local_port, remote_port;
        int rem;
 
+       uclient_get_addr(local, &local_port, &cl->local_addr);
+       uclient_get_addr(remote, &remote_port, &cl->remote_addr);
+
+       fprintf(stderr, "Connected: %s:%d -> %s:%d\n",
+               local, local_port, remote, remote_port);
+
        printf("Headers (%d): \n", cl->status_code);
        blobmsg_for_each_attr(cur, cl->meta, rem) {
                printf("%s=%s\n", blobmsg_name(cur), (char *) blobmsg_data(cur));
index 05dd3aacf2c676604a79ed004f2ffe0387dbffda..ee354c7af6b9f1c167e6cbb5c4a4e74de243015a 100644 (file)
@@ -503,6 +503,7 @@ uclient_http_send_headers(struct uclient_http *uh)
 static void uclient_http_headers_complete(struct uclient_http *uh)
 {
        enum auth_type auth_type = uh->auth_type;
+       socklen_t sl;
 
        uh->state = HTTP_STATE_RECV_DATA;
        uh->uc.meta = uh->meta.head;
@@ -515,6 +516,13 @@ static void uclient_http_headers_complete(struct uclient_http *uh)
                return;
        }
 
+       memset(&uh->uc.local_addr, 0, sizeof(uh->uc.local_addr));
+       memset(&uh->uc.remote_addr, 0, sizeof(uh->uc.remote_addr));
+
+       sl = sizeof(uh->uc.local_addr);
+       getsockname(uh->ufd.fd.fd, &uh->uc.local_addr.sa, &sl);
+       getpeername(uh->ufd.fd.fd, &uh->uc.remote_addr.sa, &sl);
+
        if (uh->uc.cb->header_done)
                uh->uc.cb->header_done(&uh->uc);
 
index 82553a56847a4dae7b526c34a2396657e556e8cd..bcb7357c40d41ec1c3258951cc7ba6eae8bb0b0f 100644 (file)
--- a/uclient.c
+++ b/uclient.c
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+#include <arpa/inet.h>
 #include <libubox/ustream-ssl.h>
 #include "uclient.h"
 #include "uclient-utils.h"
 #include "uclient-backend.h"
 
+char *uclient_get_addr(char *dest, int *port, union uclient_addr *a)
+{
+       int portval;
+       void *ptr;
+
+       switch(a->sa.sa_family) {
+       case AF_INET:
+               ptr = &a->sin.sin_addr;
+               portval = a->sin.sin_port;
+               break;
+       case AF_INET6:
+               ptr = &a->sin6.sin6_addr;
+               portval = a->sin6.sin6_port;
+               break;
+       default:
+               return strcpy(dest, "Unknown");
+       }
+
+       inet_ntop(a->sa.sa_family, ptr, dest, INET6_ADDRSTRLEN);
+       if (port)
+               *port = ntohs(portval);
+
+       return dest;
+}
+
+
 struct uclient_url __hidden *
 uclient_get_url(const char *url_str, const char *auth_str)
 {
index 65e48b2f35b68058f3fb2f7ec4ff009ded60a9d5..25990c06fca3a5b6e9855def09ae863cc3e3a0a8 100644 (file)
--- a/uclient.h
+++ b/uclient.h
@@ -18,6 +18,8 @@
 #ifndef __LIBUBOX_UCLIENT_H
 #define __LIBUBOX_UCLIENT_H
 
+#include <netinet/in.h>
+
 #include <libubox/blob.h>
 #include <libubox/ustream.h>
 #include <libubox/ustream-ssl.h>
@@ -32,10 +34,18 @@ enum uclient_error_code {
        UCLIENT_ERROR_SSL_CN_MISMATCH,
 };
 
+union uclient_addr {
+       struct sockaddr sa;
+       struct sockaddr_in sin;
+       struct sockaddr_in6 sin6;
+};
+
 struct uclient {
        const struct uclient_backend *backend;
        const struct uclient_cb *cb;
 
+       union uclient_addr local_addr, remote_addr;
+
        struct uclient_url *url;
        void *priv;
 
@@ -65,6 +75,8 @@ int uclient_read(struct uclient *cl, char *buf, int len);
 int uclient_write(struct uclient *cl, char *buf, int len);
 int uclient_request(struct uclient *cl);
 
+char *uclient_get_addr(char *dest, int *port, union uclient_addr *a);
+
 /* HTTP */
 extern const struct uclient_backend uclient_backend_http;