Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 27 additions & 12 deletions src/api/iptux-core/Models.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#ifndef IPTUX_MODELS_H
#define IPTUX_MODELS_H

#include <arpa/inet.h>
#include <gio/gio.h>
#include <memory>
#include <netinet/in.h>
#include <string>
Expand Down Expand Up @@ -56,17 +56,33 @@ typedef enum {
class PalKey {
public:
PalKey(in_addr ipv4, int port);
explicit PalKey(GSocketAddress* address);
~PalKey();

// Copy constructor
PalKey(const PalKey& other);

// Copy assignment operator
PalKey& operator=(const PalKey& other);

// Move constructor
PalKey(PalKey&& other) noexcept;

// Move assignment operator
PalKey& operator=(PalKey&& other) noexcept;

bool operator==(const PalKey& rhs) const;

in_addr GetIpv4() const { return ipv4; }
in_addr GetIpv4() const;
std::string GetIpv4String() const;
int GetPort() const { return port; }
int GetPort() const;
std::string ToString() const;

// Get the underlying GSocketAddress (increases reference count)
GSocketAddress* GetSocketAddress() const;

private:
in_addr ipv4;
int port;
GSocketAddress* address_;
};

/**
Expand All @@ -80,10 +96,10 @@ class PalKey {
class PalInfo {
public:
PalInfo(const std::string& ipv4, uint16_t port);
PalInfo(in_addr ipv4, uint16_t port);
explicit PalInfo(const PalKey& key);
~PalInfo();

PalKey GetKey() const { return PalKey(ipv4(), port_); }
const PalKey& GetKey() const { return key_; }

PalInfo& setName(const std::string& name);
const std::string& getName() const { return name; }
Expand Down Expand Up @@ -117,8 +133,8 @@ class PalInfo {
}

std::string toString() const;
in_addr ipv4() const { return ipv4_; }
uint16_t port() const { return port_; }
in_addr ipv4() const { return key_.GetIpv4(); }
uint16_t port() const { return key_.GetPort(); }

char* segdes; ///< 所在网段描述
char* photo; ///< 形象照片
Expand All @@ -137,8 +153,7 @@ class PalInfo {
PalInfo& setInBlacklist(bool value);

private:
in_addr ipv4_; ///< 好友IP
uint16_t port_; ///< 好友端口
PalKey key_; ///< 好友IP和端口
std::string icon_file_; ///< 好友头像 *
std::string user;
std::string name;
Expand Down Expand Up @@ -236,7 +251,7 @@ class NetSegment {
NetSegment();
~NetSegment();

bool ContainIP(in_addr ipv4) const;
bool ContainIP(GInetAddress* ipv4) const;
/**
* @brief return the ip count in this segment
*
Expand Down
2 changes: 1 addition & 1 deletion src/api/iptux-core/ProgramData.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class ProgramData {
FileInfo* GetShareFileInfo(uint32_t fileId);
FileInfo* GetShareFileInfo(uint32_t packetn, uint32_t filenum);

std::string FindNetSegDescription(in_addr ipv4) const;
std::string FindNetSegDescription(GInetAddress* ipv4) const;
void Lock();
void Unlock();

Expand Down
151 changes: 127 additions & 24 deletions src/iptux-core/Models.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include <cstring>
#include <netinet/in.h>
#include <sstream>
#include <unistd.h>
Expand All @@ -26,25 +27,29 @@ using namespace std;

namespace iptux {

PalInfo::PalInfo(in_addr ipv4, uint16_t port)
: segdes(NULL), photo(NULL), sign(NULL), packetn(0), rpacketn(0) {
this->ipv4_ = ipv4;
this->port_ = port;
compatible = 0;
online = 0;
changed = 0;
in_blacklist = 0;
}
PalInfo::PalInfo(const PalKey& key)
: segdes(NULL),
photo(NULL),
sign(NULL),
packetn(0),
rpacketn(0),
key_(key),
compatible(0),
online(0),
changed(0),
in_blacklist(0) {}

PalInfo::PalInfo(const string& ipv4, uint16_t port)
: segdes(NULL), photo(NULL), sign(NULL), packetn(0), rpacketn(0) {
this->ipv4_ = inAddrFromString(ipv4);
this->port_ = port;
compatible = 0;
online = 0;
changed = 0;
in_blacklist = 0;
}
: segdes(NULL),
photo(NULL),
sign(NULL),
packetn(0),
rpacketn(0),
key_(inAddrFromString(ipv4), port),
compatible(0),
online(0),
changed(0),
in_blacklist(0) {}

PalInfo::~PalInfo() {
g_free(segdes);
Expand Down Expand Up @@ -202,9 +207,22 @@ std::string NetSegment::NthIp(uint64_t i) const {
return inAddrToString(inAddrFromUint32(res));
}

bool NetSegment::ContainIP(in_addr ipv4) const {
return ipv4Compare(inAddrFromString(startip), ipv4) <= 0 &&
ipv4Compare(ipv4, inAddrFromString(endip)) <= 0;
bool NetSegment::ContainIP(GInetAddress* ipv4) const {
GInetAddress* start = g_inet_address_new_from_string(startip.c_str());
GInetAddress* end = g_inet_address_new_from_string(endip.c_str());

gsize size = g_inet_address_get_native_size(ipv4);
const guint8* ip_bytes = g_inet_address_to_bytes(ipv4);
const guint8* start_bytes = g_inet_address_to_bytes(start);
const guint8* end_bytes = g_inet_address_to_bytes(end);

int cmp_start = memcmp(ip_bytes, start_bytes, size);
int cmp_end = memcmp(ip_bytes, end_bytes, size);

g_object_unref(start);
g_object_unref(end);

return cmp_start >= 0 && cmp_end <= 0;
}

Json::Value NetSegment::ToJsonValue() const {
Expand Down Expand Up @@ -254,18 +272,103 @@ string ChipData::getSummary() const {
return "";
}

PalKey::PalKey(in_addr ipv4, int port) : ipv4(ipv4), port(port) {}
PalKey::PalKey(in_addr ipv4, int port) {
GInetAddress* inet_addr = g_inet_address_new_from_bytes(
reinterpret_cast<const guint8*>(&ipv4), G_SOCKET_FAMILY_IPV4);
address_ = g_inet_socket_address_new(inet_addr, port);
g_object_unref(inet_addr);
}

PalKey::PalKey(GSocketAddress* address) {
address_ = G_SOCKET_ADDRESS(g_object_ref(address));
}

PalKey::~PalKey() {
if (address_) {
g_object_unref(address_);
}
}

PalKey::PalKey(const PalKey& other) {
address_ = G_SOCKET_ADDRESS(g_object_ref(other.address_));
}

PalKey& PalKey::operator=(const PalKey& other) {
if (this != &other) {
if (address_) {
g_object_unref(address_);
}
address_ = G_SOCKET_ADDRESS(g_object_ref(other.address_));
}
return *this;
}

PalKey::PalKey(PalKey&& other) noexcept : address_(other.address_) {
other.address_ = nullptr;
}

PalKey& PalKey::operator=(PalKey&& other) noexcept {
if (this != &other) {
if (address_) {
g_object_unref(address_);
}
address_ = other.address_;
other.address_ = nullptr;
}
return *this;
}

in_addr PalKey::GetIpv4() const {
GInetAddress* inet_addr = g_inet_socket_address_get_address(
G_INET_SOCKET_ADDRESS(address_));

in_addr result;
gsize size = g_inet_address_get_native_size(inet_addr);
if (size == sizeof(in_addr)) {
memcpy(&result, g_inet_address_to_bytes(inet_addr), sizeof(in_addr));
} else {
// Should not happen for IPv4
memset(&result, 0, sizeof(in_addr));
}
return result;
}

string PalKey::GetIpv4String() const {
return inAddrToString(ipv4);
GInetAddress* inet_addr = g_inet_socket_address_get_address(
G_INET_SOCKET_ADDRESS(address_));
gchar* str = g_inet_address_to_string(inet_addr);
string result(str);
g_free(str);
return result;
}

int PalKey::GetPort() const {
return g_inet_socket_address_get_port(G_INET_SOCKET_ADDRESS(address_));
}

bool PalKey::operator==(const PalKey& rhs) const {
return ipv4Equal(this->ipv4, rhs.ipv4) && this->port == rhs.port;
GInetSocketAddress* this_addr = G_INET_SOCKET_ADDRESS(this->address_);
GInetSocketAddress* other_addr = G_INET_SOCKET_ADDRESS(rhs.address_);

// Compare ports
if (g_inet_socket_address_get_port(this_addr) !=
g_inet_socket_address_get_port(other_addr)) {
return false;
}

// Compare addresses
GInetAddress* this_inet = g_inet_socket_address_get_address(this_addr);
GInetAddress* other_inet = g_inet_socket_address_get_address(other_addr);

return g_inet_address_equal(this_inet, other_inet);
}

string PalKey::ToString() const {
return stringFormat("%s:%d", inAddrToString(ipv4).c_str(), port);
return stringFormat("%s:%d", GetIpv4String().c_str(), GetPort());
}

GSocketAddress* PalKey::GetSocketAddress() const {
return G_SOCKET_ADDRESS(g_object_ref(address_));
}

bool FileInfo::operator==(const FileInfo& rhs) const {
Expand Down
52 changes: 46 additions & 6 deletions src/iptux-core/ModelsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "iptux-core/Models.h"
#include "iptux-utils/TestHelper.h"
#include "iptux-utils/utils.h"
#include <arpa/inet.h>

using namespace std;
using namespace iptux;
Expand All @@ -24,16 +25,55 @@ TEST(PalKey, GetIpv4String) {
ASSERT_EQ(key1.GetIpv4String(), "1.2.3.4");
}

TEST(PalKey, GSocketAddressConstructor) {
// Test creating PalKey from GSocketAddress
GInetAddress* inet_addr = g_inet_address_new_from_string("192.168.1.100");
ASSERT_NE(inet_addr, nullptr);

GSocketAddress* socket_addr = g_inet_socket_address_new(inet_addr, 8080);
ASSERT_NE(socket_addr, nullptr);

PalKey key(socket_addr);

// Test that the values are correctly extracted
ASSERT_EQ(key.GetIpv4String(), "192.168.1.100");
ASSERT_EQ(key.GetPort(), 8080);
ASSERT_EQ(key.ToString(), "192.168.1.100:8080");

// Test GetSocketAddress method
GSocketAddress* retrieved_addr = key.GetSocketAddress();
ASSERT_NE(retrieved_addr, nullptr);

// Verify the retrieved address matches
GInetSocketAddress* inet_socket_addr = G_INET_SOCKET_ADDRESS(retrieved_addr);
ASSERT_EQ(g_inet_socket_address_get_port(inet_socket_addr), 8080);

GInetAddress* retrieved_inet =
g_inet_socket_address_get_address(inet_socket_addr);
gchar* ip_str = g_inet_address_to_string(retrieved_inet);
ASSERT_STREQ(ip_str, "192.168.1.100");
g_free(ip_str);

// Test equality with another PalKey created from in_addr
PalKey key2(inAddrFromString("192.168.1.100"), 8080);
ASSERT_EQ(key, key2);

// Cleanup
g_object_unref(retrieved_addr);
g_object_unref(socket_addr);
g_object_unref(inet_addr);
}

TEST(NetSegment, ContainIP) {
NetSegment netSegment("1.2.3.4", "1.2.4.5", "");

vector<string> ips = {"1.2.3.4", "1.2.4.5", "1.2.3.255",
"1.2.4.0", "1.2.3.5", "1.2.4.4"};

for (const string& ip : ips) {
in_addr ip1;
ASSERT_EQ(inet_pton(AF_INET, ip.c_str(), &ip1.s_addr), 1) << ip;
ASSERT_TRUE(netSegment.ContainIP(ip1));
GInetAddress* addr = g_inet_address_new_from_string(ip.c_str());
ASSERT_TRUE(netSegment.ContainIP(addr)) << ip;
g_object_unref(addr);
}

vector<string> ips2 = {
Expand All @@ -43,9 +83,9 @@ TEST(NetSegment, ContainIP) {
"100.100.100.100",
};
for (const string& ip : ips2) {
in_addr ip1;
ASSERT_EQ(inet_pton(AF_INET, ip.c_str(), &ip1), 1) << ip;
ASSERT_FALSE(netSegment.ContainIP(ip1));
GInetAddress* addr = g_inet_address_new_from_string(ip.c_str());
ASSERT_FALSE(netSegment.ContainIP(addr)) << ip;
g_object_unref(addr);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/iptux-core/ProgramData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ void ProgramData::set_port(uint16_t port, bool is_init) {
* @param ipv4 ipv4
* @return 描述串
*/
string ProgramData::FindNetSegDescription(in_addr ipv4) const {
string ProgramData::FindNetSegDescription(GInetAddress* ipv4) const {
for (size_t i = 0; i < netseg.size(); ++i) {
if (netseg[i].ContainIP(ipv4)) {
return netseg[i].description;
Expand Down
1 change: 1 addition & 0 deletions src/iptux-core/internal/RecvFileData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "config.h"
#include "RecvFileData.h"

#include <arpa/inet.h>
#include <memory>

#include <fcntl.h>
Expand Down
Loading
Loading