Skip to content

Commit

Permalink
Practicing with interposition
Browse files Browse the repository at this point in the history
  • Loading branch information
ccanel committed Apr 24, 2024
1 parent 6d0d604 commit 1b2915d
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 51 deletions.
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@ test/models
ratemon/runtime/new/.output
ratemon/runtime/new/ratemon_test

ratemon/runtime/new/client_server/*.o
ratemon/runtime/new/client_server/*.so
ratemon/runtime/new/client_server/.output/
ratemon/runtime/new/client_server/client
ratemon/runtime/new/client_server/server
44 changes: 31 additions & 13 deletions ratemon/runtime/new/client_server/Makefile
Original file line number Diff line number Diff line change
@@ -1,23 +1,41 @@
OUTPUT = .output
CC = gcc
CFLAGS = -I. -g
CXX = g++
CFLAGS = -g -std=c17 -Wall -Wextra
CXXFLAGS = -g -std=c++17 -Wall -Wextra
DEPS = common.h
CLIENT_OBJ = client.o
SERVER_OBJ = server.o
APPS = client server
INTERPS = libinterptest libinterptest_cpp

%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
.PHONY: all
all: $(APPS) $(INTERPS)

client: $(CLIENT_OBJ)
$(CC) -o $@ $^ $(CFLAGS)
$(OUTPUT):
mkdir -p $(@)

server: $(SERVER_OBJ)
$(CC) -o $@ $^ $(CFLAGS)
$(OUTPUT)/%.o: %.c $(DEPS) | $(OUTPUT)
$(CC) $(CFLAGS) -c -o $@ $<

libinterptest: interptest.c
$(CC) -shared -ldl -fPIC interptest.c -o libinterptest.so
$(APPS): %: $(OUTPUT)/%.o | $(OUTPUT)
$(CC) $(CFLAGS) -o $@ $^

$(OUTPUT)/%.so: %.c | $(OUTPUT)
$(CC) $(CFLAGS) -shared -ldl -fPIC $^ -o $@

all: client server libinterptest
$(OUTPUT)/%_cpp.so: %_cpp.cpp | $(OUTPUT)
$(CXX) $(CXXFLAGS) -shared -ldl -fPIC $^ -o $@

$(INTERPS): %: $(OUTPUT)/%.so ;

interp_server : server $(OUTPUT)/libinterptest.so
LD_PRELOAD=$(OUTPUT)/libinterptest.so ./server

interp_server_cpp : server $(OUTPUT)/libinterptest_cpp.so
LD_PRELOAD=$(OUTPUT)/libinterptest_cpp.so ./server

run_client: client
./client

.PHONY: clean
clean:
rm -f *.o *.so client server
rm -rfv $(OUTPUT) $(APPS)
36 changes: 0 additions & 36 deletions ratemon/runtime/new/client_server/interptest.c

This file was deleted.

53 changes: 53 additions & 0 deletions ratemon/runtime/new/client_server/libinterptest.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#define _GNU_SOURCE
#include <dlfcn.h>
#include <netinet/in.h> // structure for storing address information
#include <netinet/tcp.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h> // for socket APIs

int storedSockFd = 0;

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
printf("Intercepted call to 'accept'\n");

static int (*real_accept)(int, struct sockaddr *, socklen_t *) = NULL;
real_accept =
(int (*)(int, struct sockaddr *, socklen_t *))dlsym(RTLD_NEXT, "accept");
if (real_accept == NULL) {
fprintf(stderr, "Error in dlsym when querying for 'accept': %s\n",
dlerror());
return -1;
}

int ret = real_accept(sockfd, addr, addrlen);
printf("accept for FD=%d got FD=%d\n", sockfd, ret);

if (ret != -1) {
struct tcp_info info;
socklen_t tcp_info_length = (socklen_t)sizeof(info);
if (getsockopt(ret, SOL_TCP, TCP_INFO, (void *)&info, &tcp_info_length) ==
0) {
printf("TCP_INFO rtt=%u, rto=%u\n", info.tcpi_rtt, info.tcpi_rto);
} else {
printf("Error in getsockopt TCP_INFO\n");
}
}

return ret;
}

int close(int sockfd) {
printf("Intercepted call to 'close' for FD=%d\n", sockfd);

static int (*real_close)(int) = NULL;
real_close = (int (*)(int))dlsym(RTLD_NEXT, "close");
if (real_close == NULL) {
fprintf(stderr, "Error in dlsym when querying for 'close': %s\n",
dlerror());
return -1;
}

return real_close(sockfd);
;
}
64 changes: 64 additions & 0 deletions ratemon/runtime/new/client_server/libinterptest_cpp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif

#include <dlfcn.h>
#include <netinet/in.h> // structure for storing address information
#include <netinet/tcp.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h> // for socket APIs

#include <unordered_set>

std::unordered_set<int> sockfds;

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
printf("Intercepted call to 'accept'\n");

static int (*real_accept)(int, struct sockaddr *, socklen_t *) =
(int (*)(int, struct sockaddr *, socklen_t *))dlsym(RTLD_NEXT, "accept");
if (real_accept == NULL) {
fprintf(stderr, "Error in dlsym when querying for 'accept': %s\n",
dlerror());
return -1;
}

int ret = real_accept(sockfd, addr, addrlen);
printf("accept for FD=%d got FD=%d\n", sockfd, ret);

if (ret != -1) {
sockfds.insert(ret);

struct tcp_info info;
socklen_t tcp_info_length = (socklen_t)sizeof(info);
if (getsockopt(ret, SOL_TCP, TCP_INFO, (void *)&info, &tcp_info_length) ==
0) {
printf("TCP_INFO rtt=%u, rto=%u\n", info.tcpi_rtt, info.tcpi_rto);
} else {
printf("Error in getsockopt TCP_INFO\n");
}
}

return ret;
}

int close(int sockfd) {
printf("Intercepted call to 'close' for FD=%d\n", sockfd);

static int (*real_close)(int) = (int (*)(int))dlsym(RTLD_NEXT, "close");
if (real_close == NULL) {
fprintf(stderr, "Error in dlsym when querying for 'close': %s\n",
dlerror());
return -1;
}

int ret = real_close(sockfd);
if (ret != -1) {
if (sockfds.find(sockfd) != sockfds.end()) {
sockfds.erase(sockfd);
}
}

return ret;
}
4 changes: 4 additions & 0 deletions ratemon/runtime/new/client_server/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ int main(int argc, char const* argv[]) {

printf("Server done sending. Exiting...\n");

if (close(clientSocket) == -1) {
printf("Error in closing client socket\n");
return 1;
}
// close server listen socket
if (close(servSockD) == -1) {
printf("Error in closing server socket\n");
Expand Down

0 comments on commit 1b2915d

Please sign in to comment.