|
|
nono 1.7.0
//
// nono
// Copyright (C) 2025 nono project
// Licensed under nono-license.txt
//
//
// ホストネットワークの usermode (SLIRP) ドライバ
//
#pragma once
#include "netdriver.h"
#include "autofd.h"
#include "config.h"
#include "hostnet.h"
#include <poll.h>
#include <netinet/in.h>
#include <list>
#include <mutex>
typedef struct Slirp Slirp;
class SlirpThread;
class SlirpTimer;
struct FwdInfo
{
int is_udp;
struct sockaddr_in host;
struct sockaddr_in guest;
};
class NetDriverSlirp : public NetDriver
{
using inherited = NetDriver;
public:
explicit NetDriverSlirp(HostDevice *hostdev_);
~NetDriverSlirp() override;
void SetLogLevel(int) override;
bool InitDriver(bool startup) override;
int Read(NetPacket *p) override;
void Write(const void *buf, int buflen) override;
void MonitorScreenMD(TextScreen&, int y) override;
// Slirp ドライバが稼働中かどうか (高々1つなのでグローバル)
static bool IsOccupied() noexcept { return slirp_occupied; }
private:
void Close();
int txd {}; // 裏スレッドへの送信ディスクリプタ
int rxd {}; // 裏スレッドからの受信ディスクリプタ
std::unique_ptr<SlirpThread> backend /*{}*/;
// usermode を使えるのは同時に1人だけに限定する。
static bool slirp_occupied;
};
// 裏スレッド
class SlirpThread : public ThreadDevice
{
using inherited = ThreadDevice;
// major.minor.patch のバージョン番号を適当に整数にマッピングする。
static uint32 VER(uint major_, uint minor_, uint patch_) {
return (major_ << 16) + (minor_ << 8) + patch_;
}
public:
explicit SlirpThread(NetDriverSlirp *parent_);
~SlirpThread() override;
// 初期化
bool InitBackend(const std::string& key, int *rfd, int *tfd);
void Close();
void Terminate() override;
void MonitorScreen(Monitor *, TextScreen&);
// コールバック (C のコールバックから呼ばれるので public)
int AddPollCB(int fd, int slevents);
int GetReventsCB(int idx);
ssize_t SendPacketCB(const void *src, size_t srclen);
int64 ClockGetNsCB() const;
void *TimerNewCB(void (*)(void *), void *);
void TimerFreeCB(SlirpTimer *);
void TimerModCB(SlirpTimer *, int64);
void GuestErrorCB(const char *);
// エラーメッセージ。表スレッドへの連絡用。
std::string errmsg {};
private:
void ThreadRun() override;
bool ParseConfigNet(const ConfigItem&,
struct in_addr *addr, struct in_addr *mask);
bool ParseConfigNet6(const ConfigItem&, struct in6_addr *addr6, uint *len);
bool ParseConfigHostFwdEntry(const ConfigItem&, const std::string& entry,
const std::string& where);
int ParseAddrPort(const ConfigItem&, const std::string& hostport,
struct sockaddr_in *, const char *which, const std::string& where);
void Write();
// 一部のパケットをこちらで処理する。
bool WriteHook(const std::vector<uint8>&) const;
void UpdateInfo();
// スレッド終了フラグ
bool exit_requested {};
// デバッグ用。
void DumpHex(const void *, size_t) const;
void DumpFrame(const void *, size_t) const;
// Slirp ハンドル
Slirp *sl {};
std::vector<struct pollfd> pollfds {};
std::list<SlirpTimer *> timerlist {};
std::vector<FwdInfo> fwdinfo {};
struct in6_addr gw6 {};
struct in6_addr dns6 {};
// 表スレッドとの送信側/受信側パイプ。
autofd txd_r {};
autofd txd_w {};
autofd rxd_r {};
autofd rxd_w {};
// モニタ表示用の内部テーブル文字列。
char *conninfo {};
char *nbrinfo {};
std::mutex info_mtx {};
// タイマーを区別するためのデバッグ用の番号用。
int latest_timer_num {};
// libslirp のバージョン
uint32 ver {};
Monitor *monitor {};
HostNetDevice *hostnet {};
NetDriverSlirp *parent {};
};
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.