uNetworking / uWebSockets

Simple, secure & standards compliant web server for the most demanding of applications
Apache License 2.0
17.29k stars 1.75k forks source link

Get client(remote) port #1034

Closed acharkov closed 9 months ago

acharkov commented 4 years ago

Hi!

There is a function to get the remote IP address. But how to get the remote port. Is it possible?

ghost commented 4 years ago

Technically that should be possible, but where is this needed?

acharkov commented 4 years ago

Thank you for the answer! After some internal discussion with team we decided to proceed without remotePort information. It was needed for debug purposes before. But it's not an important information for the moment.

fucksophie commented 3 years ago

I'd like this feature. I need it for controlling many clients and they all use RemotePorts. I'd like to have some kind of function to retrieve it.

CMCDragonkai commented 1 year ago

Why was this closed if this didn't actually get implemented?

uNetworkingAB commented 1 year ago

It is implemented. It's called something like us_socket_remote_address or similar. Look in uSockets

CMCDragonkai commented 1 year ago

Oh has this been exposed on uWebSockets.js?

Jacob-Burckhardt commented 12 months ago

It's called something like us_socket_remote_address or similar. Look in uSockets

I couldn't get the remote port out of that function. But I got it using the following technique. Testing shows it works, but is it safe to cast us_socket_get_native_handle to uintptr_t?

#include "App.h"
#include "cassert"
#include <netinet/in.h>

using namespace std;

struct PerSocketData {};

int main() {
   uWS::App app;

   app.ws<PerSocketData>("/*", {
         .open = [](auto *ws) {
            us_socket_t *s = (us_socket_t *) ws;

            // is this cast safe?
            auto fd = (uintptr_t) us_socket_get_native_handle(0, s); 

            struct sockaddr_storage addr;
            socklen_t len = sizeof addr;
            if (getpeername(fd, (struct sockaddr*)&addr, &len)) {
               perror("getpeername");
               return;
            }

            int port;

            // deal with both IPv4 and IPv6:
            if (addr.ss_family == AF_INET) {
               struct sockaddr_in *s = (struct sockaddr_in *)&addr;
               port = ntohs(s->sin_port);
            } else if (addr.ss_family == AF_INET6) {
               struct sockaddr_in6 *s = (struct sockaddr_in6 *)&addr;
               port = ntohs(s->sin6_port);
            } else {
               assert(0);
            }

            cout << "got connection from port " << port << endl;

            ws->send("from server", uWS::OpCode::TEXT);
         },
           }).listen(9001, [](auto *) {
           });

   app.run();
}
uNetworkingAB commented 12 months ago

Interesting, looks like there is only int us_socket_local_port(int ssl, struct us_socket_t *s);

Why would you need ephemeral port? You can PR the feature as int us_socket_remote_port(int ssl, struct us_socket_t *s);

Jacob-Burckhardt commented 12 months ago

Why would you need ephemeral port?

I want to log it along with other logs related to my app. Sometimes my logs don't have enough info so I use other tools like Wireshark and lsof which also show the ephemeral port. I want to cross-reference the many connections in these tools with the logs in my uWebSockets app.

I'll try to add the function you suggested.

Jacob-Burckhardt commented 11 months ago

Thanks for accepting my PR. That means you can close this issue.