Compare commits
No commits in common. "684fa1c4b01366b44cf15835237ef176e3722148" and "f022a1b08ffd73982eb24042c318f98b3cb982fb" have entirely different histories.
684fa1c4b0
...
f022a1b08f
|
|
@ -9,10 +9,6 @@ namespace BAN
|
||||||
|
|
||||||
struct IPv4Address
|
struct IPv4Address
|
||||||
{
|
{
|
||||||
constexpr IPv4Address()
|
|
||||||
: IPv4Address(0)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
constexpr IPv4Address(uint32_t u32_address)
|
constexpr IPv4Address(uint32_t u32_address)
|
||||||
{
|
{
|
||||||
raw = u32_address;
|
raw = u32_address;
|
||||||
|
|
|
||||||
|
|
@ -6,19 +6,6 @@
|
||||||
|
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
|
|
||||||
// This is ugly but my clangd does not like including
|
|
||||||
// intrinsic headers at all
|
|
||||||
#if !defined(__SSE__) || !defined(__SSE2__)
|
|
||||||
#pragma GCC push_options
|
|
||||||
#ifndef __SSE__
|
|
||||||
#pragma GCC target("sse")
|
|
||||||
#endif
|
|
||||||
#ifndef __SSE2__
|
|
||||||
#pragma GCC target("sse2")
|
|
||||||
#endif
|
|
||||||
#define BAN_MATH_POP_OPTIONS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace BAN::Math
|
namespace BAN::Math
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -180,7 +167,7 @@ namespace BAN::Math
|
||||||
template<floating_point T>
|
template<floating_point T>
|
||||||
static T modf(T x, T* iptr)
|
static T modf(T x, T* iptr)
|
||||||
{
|
{
|
||||||
const T frac = BAN::Math::fmod<T>(x, (T)1.0);
|
const T frac = BAN::Math::fmod<T>(x, 1);
|
||||||
*iptr = x - frac;
|
*iptr = x - frac;
|
||||||
return frac;
|
return frac;
|
||||||
}
|
}
|
||||||
|
|
@ -188,15 +175,15 @@ namespace BAN::Math
|
||||||
template<floating_point T>
|
template<floating_point T>
|
||||||
inline constexpr T frexp(T num, int* exp)
|
inline constexpr T frexp(T num, int* exp)
|
||||||
{
|
{
|
||||||
if (num == (T)0.0)
|
if (num == 0.0)
|
||||||
{
|
{
|
||||||
*exp = 0;
|
*exp = 0;
|
||||||
return (T)0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
T e;
|
T _exp;
|
||||||
asm("fxtract" : "+t"(num), "=u"(e));
|
asm("fxtract" : "+t"(num), "=u"(_exp));
|
||||||
*exp = (int)e + 1;
|
*exp = (int)_exp + 1;
|
||||||
return num / (T)2.0;
|
return num / (T)2.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -264,7 +251,6 @@ namespace BAN::Math
|
||||||
"fstp %%st(1);"
|
"fstp %%st(1);"
|
||||||
: "+t"(x)
|
: "+t"(x)
|
||||||
);
|
);
|
||||||
|
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -277,9 +263,18 @@ namespace BAN::Math
|
||||||
template<floating_point T>
|
template<floating_point T>
|
||||||
inline constexpr T pow(T x, T y)
|
inline constexpr T pow(T x, T y)
|
||||||
{
|
{
|
||||||
if (x == (T)0.0)
|
asm(
|
||||||
return (T)0.0;
|
"fyl2x;"
|
||||||
return exp2<T>(y * log2<T>(x));
|
"fld1;"
|
||||||
|
"fld %%st(1);"
|
||||||
|
"fprem;"
|
||||||
|
"f2xm1;"
|
||||||
|
"faddp;"
|
||||||
|
"fscale;"
|
||||||
|
: "+t"(x), "+u"(y)
|
||||||
|
);
|
||||||
|
|
||||||
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<floating_point T>
|
template<floating_point T>
|
||||||
|
|
@ -314,28 +309,17 @@ namespace BAN::Math
|
||||||
|
|
||||||
template<floating_point T>
|
template<floating_point T>
|
||||||
inline constexpr T sqrt(T x)
|
inline constexpr T sqrt(T x)
|
||||||
{
|
|
||||||
if constexpr(BAN::is_same_v<T, float>)
|
|
||||||
{
|
|
||||||
using v4sf = float __attribute__((vector_size(16)));
|
|
||||||
return __builtin_ia32_sqrtss((v4sf) { x, 0.0f, 0.0f, 0.0f })[0];
|
|
||||||
}
|
|
||||||
else if constexpr(BAN::is_same_v<T, double>)
|
|
||||||
{
|
|
||||||
using v2df = double __attribute__((vector_size(16)));
|
|
||||||
return __builtin_ia32_sqrtsd((v2df) { x, 0.0 })[0];
|
|
||||||
}
|
|
||||||
else if constexpr(BAN::is_same_v<T, long double>)
|
|
||||||
{
|
{
|
||||||
asm("fsqrt" : "+t"(x));
|
asm("fsqrt" : "+t"(x));
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
template<floating_point T>
|
template<floating_point T>
|
||||||
inline constexpr T cbrt(T value)
|
inline constexpr T cbrt(T value)
|
||||||
{
|
{
|
||||||
return pow<T>(value, (T)1.0 / (T)3.0);
|
if (value == 0.0)
|
||||||
|
return 0.0;
|
||||||
|
return pow<T>(value, 1.0 / 3.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<floating_point T>
|
template<floating_point T>
|
||||||
|
|
@ -362,21 +346,30 @@ namespace BAN::Math
|
||||||
inline constexpr T tan(T x)
|
inline constexpr T tan(T x)
|
||||||
{
|
{
|
||||||
T one, ret;
|
T one, ret;
|
||||||
asm("fptan" : "=t"(one), "=u"(ret) : "0"(x));
|
asm(
|
||||||
|
"fptan"
|
||||||
|
: "=t"(one), "=u"(ret)
|
||||||
|
: "0"(x)
|
||||||
|
);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<floating_point T>
|
template<floating_point T>
|
||||||
inline constexpr T atan2(T y, T x)
|
inline constexpr T atan2(T y, T x)
|
||||||
{
|
{
|
||||||
asm("fpatan" : "+t"(x) : "u"(y) : "st(1)");
|
asm(
|
||||||
|
"fpatan"
|
||||||
|
: "+t"(x)
|
||||||
|
: "u"(y)
|
||||||
|
: "st(1)"
|
||||||
|
);
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<floating_point T>
|
template<floating_point T>
|
||||||
inline constexpr T atan(T x)
|
inline constexpr T atan(T x)
|
||||||
{
|
{
|
||||||
return atan2<T>(x, (T)1.0);
|
return atan2<T>(x, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<floating_point T>
|
template<floating_point T>
|
||||||
|
|
@ -385,10 +378,10 @@ namespace BAN::Math
|
||||||
if (x == (T)0.0)
|
if (x == (T)0.0)
|
||||||
return (T)0.0;
|
return (T)0.0;
|
||||||
if (x == (T)1.0)
|
if (x == (T)1.0)
|
||||||
return +numbers::pi_v<T> / (T)2.0;
|
return numbers::pi_v<T> / (T)2.0;
|
||||||
if (x == (T)-1.0)
|
if (x == (T)-1.0)
|
||||||
return -numbers::pi_v<T> / (T)2.0;
|
return -numbers::pi_v<T> / (T)2.0;
|
||||||
return (T)2.0 * atan<T>(x / ((T)1.0 + sqrt<T>((T)1.0 - x * x)));
|
return (T)2.0 * atan<T>(x / (T(1.0) + sqrt<T>((T)1.0 - x * x)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<floating_point T>
|
template<floating_point T>
|
||||||
|
|
@ -418,7 +411,7 @@ namespace BAN::Math
|
||||||
template<floating_point T>
|
template<floating_point T>
|
||||||
inline constexpr T tanh(T x)
|
inline constexpr T tanh(T x)
|
||||||
{
|
{
|
||||||
const T exp_px = exp<T>(+x);
|
const T exp_px = exp<T>(x);
|
||||||
const T exp_nx = exp<T>(-x);
|
const T exp_nx = exp<T>(-x);
|
||||||
return (exp_px - exp_nx) / (exp_px + exp_nx);
|
return (exp_px - exp_nx) / (exp_px + exp_nx);
|
||||||
}
|
}
|
||||||
|
|
@ -448,8 +441,3 @@ namespace BAN::Math
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BAN_MATH_POP_OPTIONS
|
|
||||||
#undef BAN_MATH_POP_OPTIONS
|
|
||||||
#pragma GCC pop_options
|
|
||||||
#endif
|
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,10 @@
|
||||||
namespace BAN
|
namespace BAN
|
||||||
{
|
{
|
||||||
#if defined(__is_kernel)
|
#if defined(__is_kernel)
|
||||||
static constexpr void*(*allocator)(size_t) = kmalloc;
|
static constexpr void*(&allocator)(size_t) = kmalloc;
|
||||||
static constexpr void*(*reallocator)(void*, size_t) = nullptr;
|
static constexpr void(&deallocator)(void*) = kfree;
|
||||||
static constexpr void(*deallocator)(void*) = kfree;
|
|
||||||
#else
|
#else
|
||||||
static constexpr void*(*allocator)(size_t) = malloc;
|
static constexpr void*(&allocator)(size_t) = malloc;
|
||||||
static constexpr void*(*reallocator)(void*, size_t) = realloc;
|
static constexpr void(&deallocator)(void*) = free;
|
||||||
static constexpr void(*deallocator)(void*) = free;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@ namespace BAN
|
||||||
|
|
||||||
value_type* data() const
|
value_type* data() const
|
||||||
{
|
{
|
||||||
|
ASSERT(m_data);
|
||||||
return m_data;
|
return m_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,6 +84,7 @@ namespace BAN
|
||||||
|
|
||||||
Span slice(size_type start, size_type length = ~size_type(0)) const
|
Span slice(size_type start, size_type length = ~size_type(0)) const
|
||||||
{
|
{
|
||||||
|
ASSERT(m_data);
|
||||||
ASSERT(start <= m_size);
|
ASSERT(start <= m_size);
|
||||||
if (length == ~size_type(0))
|
if (length == ~size_type(0))
|
||||||
length = m_size - start;
|
length = m_size - start;
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ namespace BAN
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using size_type = size_t;
|
using size_type = size_t;
|
||||||
using value_type = char;
|
|
||||||
using iterator = IteratorSimple<char, String>;
|
using iterator = IteratorSimple<char, String>;
|
||||||
using const_iterator = ConstIteratorSimple<char, String>;
|
using const_iterator = ConstIteratorSimple<char, String>;
|
||||||
static constexpr size_type sso_capacity = 15;
|
static constexpr size_type sso_capacity = 15;
|
||||||
|
|
@ -353,9 +352,10 @@ namespace BAN::Formatter
|
||||||
{
|
{
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
void print_argument(F putc, const String& string, const ValueFormat& format)
|
void print_argument(F putc, const String& string, const ValueFormat&)
|
||||||
{
|
{
|
||||||
print_argument(putc, string.sv(), format);
|
for (String::size_type i = 0; i < string.size(); i++)
|
||||||
|
putc(string[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ namespace BAN
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using size_type = size_t;
|
using size_type = size_t;
|
||||||
using value_type = char;
|
|
||||||
using const_iterator = ConstIteratorSimple<char, StringView>;
|
using const_iterator = ConstIteratorSimple<char, StringView>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -247,12 +246,10 @@ namespace BAN::Formatter
|
||||||
{
|
{
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
void print_argument(F putc, const StringView& sv, const ValueFormat& format)
|
void print_argument(F putc, const StringView& sv, const ValueFormat&)
|
||||||
{
|
{
|
||||||
for (StringView::size_type i = 0; i < sv.size(); i++)
|
for (StringView::size_type i = 0; i < sv.size(); i++)
|
||||||
putc(sv[i]);
|
putc(sv[i]);
|
||||||
for (int i = sv.size(); i < format.fill; i++)
|
|
||||||
putc(' ');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,9 +61,6 @@ namespace BAN
|
||||||
template<typename T> struct is_move_constructible { static constexpr bool value = is_constructible_v<T, T&&>; };
|
template<typename T> struct is_move_constructible { static constexpr bool value = is_constructible_v<T, T&&>; };
|
||||||
template<typename T> inline constexpr bool is_move_constructible_v = is_move_constructible<T>::value;
|
template<typename T> inline constexpr bool is_move_constructible_v = is_move_constructible<T>::value;
|
||||||
|
|
||||||
template<typename T> struct is_trivially_copyable { static constexpr bool value = __is_trivially_copyable(T); };
|
|
||||||
template<typename T> inline constexpr bool is_trivially_copyable_v = is_trivially_copyable<T>::value;
|
|
||||||
|
|
||||||
template<typename T> struct is_integral { static constexpr bool value = requires (T t, T* p, void (*f)(T)) { reinterpret_cast<T>(t); f(0); p + t; }; };
|
template<typename T> struct is_integral { static constexpr bool value = requires (T t, T* p, void (*f)(T)) { reinterpret_cast<T>(t); f(0); p + t; }; };
|
||||||
template<typename T> inline constexpr bool is_integral_v = is_integral<T>::value;
|
template<typename T> inline constexpr bool is_integral_v = is_integral<T>::value;
|
||||||
template<typename T> concept integral = is_integral_v<T>;
|
template<typename T> concept integral = is_integral_v<T>;
|
||||||
|
|
|
||||||
|
|
@ -381,35 +381,10 @@ namespace BAN
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ErrorOr<void> Vector<T>::ensure_capacity(size_type size)
|
ErrorOr<void> Vector<T>::ensure_capacity(size_type size)
|
||||||
{
|
{
|
||||||
static_assert(alignof(T) <= alignof(max_align_t), "over aligned types not supported");
|
|
||||||
|
|
||||||
if (m_capacity >= size)
|
if (m_capacity >= size)
|
||||||
return {};
|
return {};
|
||||||
|
size_type new_cap = BAN::Math::max<size_type>(size, m_capacity * 2);
|
||||||
const size_type new_cap = BAN::Math::max<size_type>(size, m_capacity * 2);
|
T* new_data = (T*)BAN::allocator(new_cap * sizeof(T));
|
||||||
|
|
||||||
if constexpr (BAN::is_trivially_copyable_v<T>)
|
|
||||||
{
|
|
||||||
if constexpr (BAN::reallocator)
|
|
||||||
{
|
|
||||||
auto* new_data = static_cast<T*>(BAN::reallocator(m_data, new_cap * sizeof(T)));
|
|
||||||
if (new_data == nullptr)
|
|
||||||
return Error::from_errno(ENOMEM);
|
|
||||||
m_data = new_data;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto* new_data = static_cast<T*>(BAN::allocator(new_cap * sizeof(T)));
|
|
||||||
if (new_data == nullptr)
|
|
||||||
return Error::from_errno(ENOMEM);
|
|
||||||
memcpy(new_data, m_data, m_size * sizeof(T));
|
|
||||||
BAN::deallocator(m_data);
|
|
||||||
m_data = new_data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto* new_data = static_cast<T*>(BAN::allocator(new_cap * sizeof(T)));
|
|
||||||
if (new_data == nullptr)
|
if (new_data == nullptr)
|
||||||
return Error::from_errno(ENOMEM);
|
return Error::from_errno(ENOMEM);
|
||||||
for (size_type i = 0; i < m_size; i++)
|
for (size_type i = 0; i < m_size; i++)
|
||||||
|
|
@ -419,8 +394,6 @@ namespace BAN
|
||||||
}
|
}
|
||||||
BAN::deallocator(m_data);
|
BAN::deallocator(m_data);
|
||||||
m_data = new_data;
|
m_data = new_data;
|
||||||
}
|
|
||||||
|
|
||||||
m_capacity = new_cap;
|
m_capacity = new_cap;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,6 @@ set(KERNEL_SOURCES
|
||||||
kernel/InterruptController.cpp
|
kernel/InterruptController.cpp
|
||||||
kernel/kernel.cpp
|
kernel/kernel.cpp
|
||||||
kernel/Lock/SpinLock.cpp
|
kernel/Lock/SpinLock.cpp
|
||||||
kernel/Memory/ByteRingBuffer.cpp
|
|
||||||
kernel/Memory/DMARegion.cpp
|
kernel/Memory/DMARegion.cpp
|
||||||
kernel/Memory/FileBackedRegion.cpp
|
kernel/Memory/FileBackedRegion.cpp
|
||||||
kernel/Memory/Heap.cpp
|
kernel/Memory/Heap.cpp
|
||||||
|
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <kernel/FS/Inode.h>
|
|
||||||
|
|
||||||
namespace Kernel
|
|
||||||
{
|
|
||||||
|
|
||||||
class EventFD final : public Inode
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static BAN::ErrorOr<BAN::RefPtr<Inode>> create(uint64_t initval, bool semaphore);
|
|
||||||
|
|
||||||
ino_t ino() const override { return 0; }
|
|
||||||
Mode mode() const override { return { Mode::IFCHR | Mode::IRUSR | Mode::IWUSR }; }
|
|
||||||
nlink_t nlink() const override { return ref_count(); }
|
|
||||||
uid_t uid() const override { return 0; }
|
|
||||||
gid_t gid() const override { return 0; }
|
|
||||||
off_t size() const override { return 0; }
|
|
||||||
timespec atime() const override { return {}; }
|
|
||||||
timespec mtime() const override { return {}; }
|
|
||||||
timespec ctime() const override { return {}; }
|
|
||||||
blksize_t blksize() const override { return 8; }
|
|
||||||
blkcnt_t blocks() const override { return 0; }
|
|
||||||
dev_t dev() const override { return 0; }
|
|
||||||
dev_t rdev() const override { return 0; }
|
|
||||||
|
|
||||||
const FileSystem* filesystem() const override { return nullptr; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override;
|
|
||||||
BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) override;
|
|
||||||
BAN::ErrorOr<void> fsync_impl() final override { return {}; }
|
|
||||||
|
|
||||||
bool can_read_impl() const override { return m_value > 0; }
|
|
||||||
bool can_write_impl() const override { return m_value < UINT64_MAX - 1; }
|
|
||||||
bool has_error_impl() const override { return false; }
|
|
||||||
bool has_hungup_impl() const override { return false; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
EventFD(uint64_t initval, bool is_semaphore)
|
|
||||||
: m_is_semaphore(is_semaphore)
|
|
||||||
, m_value(initval)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
private:
|
|
||||||
const bool m_is_semaphore;
|
|
||||||
uint64_t m_value;
|
|
||||||
|
|
||||||
ThreadBlocker m_thread_blocker;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
#include <BAN/Array.h>
|
#include <BAN/Array.h>
|
||||||
#include <kernel/FS/Inode.h>
|
#include <kernel/FS/Inode.h>
|
||||||
#include <kernel/Memory/ByteRingBuffer.h>
|
|
||||||
#include <kernel/ThreadBlocker.h>
|
#include <kernel/ThreadBlocker.h>
|
||||||
|
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
|
|
@ -39,7 +38,7 @@ namespace Kernel
|
||||||
virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) override;
|
virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) override;
|
||||||
virtual BAN::ErrorOr<void> fsync_impl() final override { return {}; }
|
virtual BAN::ErrorOr<void> fsync_impl() final override { return {}; }
|
||||||
|
|
||||||
virtual bool can_read_impl() const override { return !m_buffer->empty(); }
|
virtual bool can_read_impl() const override { return m_buffer_size > 0; }
|
||||||
virtual bool can_write_impl() const override { return true; }
|
virtual bool can_write_impl() const override { return true; }
|
||||||
virtual bool has_error_impl() const override { return m_reading_count == 0; }
|
virtual bool has_error_impl() const override { return m_reading_count == 0; }
|
||||||
virtual bool has_hungup_impl() const override { return m_writing_count == 0; }
|
virtual bool has_hungup_impl() const override { return m_writing_count == 0; }
|
||||||
|
|
@ -55,7 +54,9 @@ namespace Kernel
|
||||||
timespec m_ctime {};
|
timespec m_ctime {};
|
||||||
ThreadBlocker m_thread_blocker;
|
ThreadBlocker m_thread_blocker;
|
||||||
|
|
||||||
BAN::UniqPtr<ByteRingBuffer> m_buffer;
|
BAN::Array<uint8_t, PAGE_SIZE> m_buffer;
|
||||||
|
BAN::Atomic<size_t> m_buffer_size { 0 };
|
||||||
|
size_t m_buffer_tail { 0 };
|
||||||
|
|
||||||
BAN::Atomic<uint32_t> m_writing_count { 1 };
|
BAN::Atomic<uint32_t> m_writing_count { 1 };
|
||||||
BAN::Atomic<uint32_t> m_reading_count { 1 };
|
BAN::Atomic<uint32_t> m_reading_count { 1 };
|
||||||
|
|
|
||||||
|
|
@ -1,76 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <BAN/ByteSpan.h>
|
|
||||||
#include <BAN/UniqPtr.h>
|
|
||||||
#include <BAN/Vector.h>
|
|
||||||
|
|
||||||
#include <kernel/Memory/Types.h>
|
|
||||||
|
|
||||||
namespace Kernel
|
|
||||||
{
|
|
||||||
|
|
||||||
class ByteRingBuffer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static BAN::ErrorOr<BAN::UniqPtr<ByteRingBuffer>> create(size_t size);
|
|
||||||
~ByteRingBuffer();
|
|
||||||
|
|
||||||
void push(BAN::ConstByteSpan data)
|
|
||||||
{
|
|
||||||
ASSERT(data.size() + m_size <= m_capacity);
|
|
||||||
uint8_t* buffer_head = reinterpret_cast<uint8_t*>(m_vaddr) + (m_tail + m_size) % m_capacity;
|
|
||||||
memcpy(buffer_head, data.data(), data.size());
|
|
||||||
m_size += data.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void pop(size_t size)
|
|
||||||
{
|
|
||||||
ASSERT(size <= m_size);
|
|
||||||
m_tail = (m_tail + size) % m_capacity;
|
|
||||||
m_size -= size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pop_back(size_t size)
|
|
||||||
{
|
|
||||||
ASSERT(size <= m_size);
|
|
||||||
m_size -= size;
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::ConstByteSpan get_data() const
|
|
||||||
{
|
|
||||||
const uint8_t* base = reinterpret_cast<const uint8_t*>(m_vaddr);
|
|
||||||
return { base + m_tail, m_size };
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t front() const
|
|
||||||
{
|
|
||||||
ASSERT(!empty());
|
|
||||||
return reinterpret_cast<const uint8_t*>(m_vaddr)[m_tail];
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t back() const
|
|
||||||
{
|
|
||||||
ASSERT(!empty());
|
|
||||||
return reinterpret_cast<const uint8_t*>(m_vaddr)[m_tail + m_size];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool empty() const { return m_size == 0; }
|
|
||||||
bool full() const { return m_size == m_capacity; }
|
|
||||||
size_t free() const { return m_capacity - m_size; }
|
|
||||||
size_t size() const { return m_size; }
|
|
||||||
size_t capacity() const { return m_capacity; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
ByteRingBuffer(size_t capacity)
|
|
||||||
: m_capacity(capacity)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
private:
|
|
||||||
size_t m_size { 0 };
|
|
||||||
size_t m_tail { 0 };
|
|
||||||
const size_t m_capacity;
|
|
||||||
|
|
||||||
vaddr_t m_vaddr { 0 };
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -31,18 +31,35 @@ namespace Kernel
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static BAN::ErrorOr<BAN::UniqPtr<ARPTable>> create();
|
static BAN::ErrorOr<BAN::UniqPtr<ARPTable>> create();
|
||||||
|
~ARPTable();
|
||||||
|
|
||||||
BAN::ErrorOr<BAN::MACAddress> get_mac_from_ipv4(NetworkInterface&, BAN::IPv4Address);
|
BAN::ErrorOr<BAN::MACAddress> get_mac_from_ipv4(NetworkInterface&, BAN::IPv4Address);
|
||||||
|
|
||||||
BAN::ErrorOr<void> handle_arp_packet(NetworkInterface&, BAN::ConstByteSpan);
|
void add_arp_packet(NetworkInterface&, BAN::ConstByteSpan);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ARPTable() = default;
|
ARPTable();
|
||||||
|
|
||||||
|
void packet_handle_task();
|
||||||
|
BAN::ErrorOr<void> handle_arp_packet(NetworkInterface&, const ARPPacket&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SpinLock m_arp_table_lock;
|
struct PendingArpPacket
|
||||||
|
{
|
||||||
|
NetworkInterface& interface;
|
||||||
|
ARPPacket packet;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
SpinLock m_table_lock;
|
||||||
|
SpinLock m_pending_lock;
|
||||||
|
|
||||||
BAN::HashMap<BAN::IPv4Address, BAN::MACAddress> m_arp_table;
|
BAN::HashMap<BAN::IPv4Address, BAN::MACAddress> m_arp_table;
|
||||||
|
|
||||||
|
Thread* m_thread { nullptr };
|
||||||
|
BAN::CircularQueue<PendingArpPacket, 128> m_pending_packets;
|
||||||
|
ThreadBlocker m_pending_thread_blocker;
|
||||||
|
|
||||||
friend class BAN::UniqPtr<ARPTable>;
|
friend class BAN::UniqPtr<ARPTable>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,14 +23,14 @@ namespace Kernel
|
||||||
static BAN::ErrorOr<BAN::RefPtr<E1000>> create(PCI::Device&);
|
static BAN::ErrorOr<BAN::RefPtr<E1000>> create(PCI::Device&);
|
||||||
~E1000();
|
~E1000();
|
||||||
|
|
||||||
BAN::MACAddress get_mac_address() const override { return m_mac_address; }
|
virtual BAN::MACAddress get_mac_address() const override { return m_mac_address; }
|
||||||
|
|
||||||
bool link_up() override { return m_link_up; }
|
virtual bool link_up() override { return m_link_up; }
|
||||||
int link_speed() override;
|
virtual int link_speed() override;
|
||||||
|
|
||||||
size_t payload_mtu() const override { return E1000_RX_BUFFER_SIZE - sizeof(EthernetHeader); }
|
virtual size_t payload_mtu() const override { return E1000_RX_BUFFER_SIZE - sizeof(EthernetHeader); }
|
||||||
|
|
||||||
void handle_irq() final override;
|
virtual void handle_irq() final override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
E1000(PCI::Device& pci_device)
|
E1000(PCI::Device& pci_device)
|
||||||
|
|
@ -45,12 +45,12 @@ namespace Kernel
|
||||||
uint32_t read32(uint16_t reg);
|
uint32_t read32(uint16_t reg);
|
||||||
void write32(uint16_t reg, uint32_t value);
|
void write32(uint16_t reg, uint32_t value);
|
||||||
|
|
||||||
BAN::ErrorOr<void> send_bytes(BAN::MACAddress destination, EtherType protocol, BAN::Span<const BAN::ConstByteSpan> payload) override;
|
virtual BAN::ErrorOr<void> send_bytes(BAN::MACAddress destination, EtherType protocol, BAN::ConstByteSpan) override;
|
||||||
|
|
||||||
bool can_read_impl() const override { return false; }
|
virtual bool can_read_impl() const override { return false; }
|
||||||
bool can_write_impl() const override { return false; }
|
virtual bool can_write_impl() const override { return false; }
|
||||||
bool has_error_impl() const override { return false; }
|
virtual bool has_error_impl() const override { return false; }
|
||||||
bool has_hungup_impl() const override { return false; }
|
virtual bool has_hungup_impl() const override { return false; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BAN::ErrorOr<void> read_mac_address();
|
BAN::ErrorOr<void> read_mac_address();
|
||||||
|
|
@ -61,7 +61,7 @@ namespace Kernel
|
||||||
void enable_link();
|
void enable_link();
|
||||||
BAN::ErrorOr<void> enable_interrupt();
|
BAN::ErrorOr<void> enable_interrupt();
|
||||||
|
|
||||||
void receive_thread();
|
void handle_receive();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
PCI::Device& m_pci_device;
|
PCI::Device& m_pci_device;
|
||||||
|
|
@ -75,10 +75,6 @@ namespace Kernel
|
||||||
BAN::UniqPtr<DMARegion> m_tx_descriptor_region;
|
BAN::UniqPtr<DMARegion> m_tx_descriptor_region;
|
||||||
SpinLock m_lock;
|
SpinLock m_lock;
|
||||||
|
|
||||||
bool m_thread_should_die { false };
|
|
||||||
BAN::Atomic<bool> m_thread_is_dead { true };
|
|
||||||
ThreadBlocker m_thread_blocker;
|
|
||||||
|
|
||||||
BAN::MACAddress m_mac_address {};
|
BAN::MACAddress m_mac_address {};
|
||||||
bool m_link_up { false };
|
bool m_link_up { false };
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,8 @@ namespace Kernel
|
||||||
static BAN::ErrorOr<BAN::RefPtr<E1000E>> create(PCI::Device&);
|
static BAN::ErrorOr<BAN::RefPtr<E1000E>> create(PCI::Device&);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void detect_eeprom() override;
|
virtual void detect_eeprom() override;
|
||||||
uint32_t eeprom_read(uint8_t addr) override;
|
virtual uint32_t eeprom_read(uint8_t addr) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
E1000E(PCI::Device& pci_device)
|
E1000E(PCI::Device& pci_device)
|
||||||
|
|
|
||||||
|
|
@ -38,10 +38,11 @@ namespace Kernel
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static BAN::ErrorOr<BAN::UniqPtr<IPv4Layer>> create();
|
static BAN::ErrorOr<BAN::UniqPtr<IPv4Layer>> create();
|
||||||
|
~IPv4Layer();
|
||||||
|
|
||||||
ARPTable& arp_table() { return *m_arp_table; }
|
ARPTable& arp_table() { return *m_arp_table; }
|
||||||
|
|
||||||
BAN::ErrorOr<void> handle_ipv4_packet(NetworkInterface&, BAN::ConstByteSpan);
|
void add_ipv4_packet(NetworkInterface&, BAN::ConstByteSpan);
|
||||||
|
|
||||||
virtual void unbind_socket(uint16_t port) override;
|
virtual void unbind_socket(uint16_t port) override;
|
||||||
virtual BAN::ErrorOr<void> bind_socket_with_target(BAN::RefPtr<NetworkSocket>, const sockaddr* target_address, socklen_t target_address_len) override;
|
virtual BAN::ErrorOr<void> bind_socket_with_target(BAN::RefPtr<NetworkSocket>, const sockaddr* target_address, socklen_t target_address_len) override;
|
||||||
|
|
@ -54,14 +55,34 @@ namespace Kernel
|
||||||
virtual size_t header_size() const override { return sizeof(IPv4Header); }
|
virtual size_t header_size() const override { return sizeof(IPv4Header); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IPv4Layer() = default;
|
IPv4Layer();
|
||||||
|
|
||||||
|
void add_ipv4_header(BAN::ByteSpan packet, BAN::IPv4Address src_ipv4, BAN::IPv4Address dst_ipv4, uint8_t protocol) const;
|
||||||
|
|
||||||
BAN::ErrorOr<in_port_t> find_free_port();
|
BAN::ErrorOr<in_port_t> find_free_port();
|
||||||
|
|
||||||
private:
|
void packet_handle_task();
|
||||||
BAN::UniqPtr<ARPTable> m_arp_table;
|
BAN::ErrorOr<void> handle_ipv4_packet(NetworkInterface&, BAN::ByteSpan);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct PendingIPv4Packet
|
||||||
|
{
|
||||||
|
NetworkInterface& interface;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
RecursiveSpinLock m_bound_socket_lock;
|
RecursiveSpinLock m_bound_socket_lock;
|
||||||
|
|
||||||
|
BAN::UniqPtr<ARPTable> m_arp_table;
|
||||||
|
Thread* m_thread { nullptr };
|
||||||
|
|
||||||
|
static constexpr size_t pending_packet_buffer_size = 128 * PAGE_SIZE;
|
||||||
|
BAN::UniqPtr<VirtualRange> m_pending_packet_buffer;
|
||||||
|
BAN::CircularQueue<PendingIPv4Packet, 128> m_pending_packets;
|
||||||
|
ThreadBlocker m_pending_thread_blocker;
|
||||||
|
SpinLock m_pending_lock;
|
||||||
|
size_t m_pending_total_size { 0 };
|
||||||
|
|
||||||
BAN::HashMap<int, BAN::WeakPtr<NetworkSocket>> m_bound_sockets;
|
BAN::HashMap<int, BAN::WeakPtr<NetworkSocket>> m_bound_sockets;
|
||||||
|
|
||||||
friend class BAN::UniqPtr<IPv4Layer>;
|
friend class BAN::UniqPtr<IPv4Layer>;
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static constexpr size_t buffer_size = BAN::numeric_limits<uint16_t>::max() + 1;
|
static constexpr size_t buffer_size = BAN::numeric_limits<uint16_t>::max() + 1;
|
||||||
static constexpr size_t buffer_count = 32;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static BAN::ErrorOr<BAN::RefPtr<LoopbackInterface>> create();
|
static BAN::ErrorOr<BAN::RefPtr<LoopbackInterface>> create();
|
||||||
|
|
@ -25,9 +24,8 @@ namespace Kernel
|
||||||
LoopbackInterface()
|
LoopbackInterface()
|
||||||
: NetworkInterface(Type::Loopback)
|
: NetworkInterface(Type::Loopback)
|
||||||
{}
|
{}
|
||||||
~LoopbackInterface();
|
|
||||||
|
|
||||||
BAN::ErrorOr<void> send_bytes(BAN::MACAddress destination, EtherType protocol, BAN::Span<const BAN::ConstByteSpan> payload) override;
|
BAN::ErrorOr<void> send_bytes(BAN::MACAddress destination, EtherType protocol, BAN::ConstByteSpan) override;
|
||||||
|
|
||||||
bool can_read_impl() const override { return false; }
|
bool can_read_impl() const override { return false; }
|
||||||
bool can_write_impl() const override { return false; }
|
bool can_write_impl() const override { return false; }
|
||||||
|
|
@ -35,27 +33,8 @@ namespace Kernel
|
||||||
bool has_hungup_impl() const override { return false; }
|
bool has_hungup_impl() const override { return false; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void receive_thread();
|
SpinLock m_buffer_lock;
|
||||||
|
|
||||||
private:
|
|
||||||
struct Descriptor
|
|
||||||
{
|
|
||||||
uint8_t* addr;
|
|
||||||
uint32_t size;
|
|
||||||
uint8_t state;
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
Mutex m_buffer_lock;
|
|
||||||
BAN::UniqPtr<VirtualRange> m_buffer;
|
BAN::UniqPtr<VirtualRange> m_buffer;
|
||||||
|
|
||||||
uint32_t m_buffer_tail { 0 };
|
|
||||||
uint32_t m_buffer_head { 0 };
|
|
||||||
Descriptor m_descriptors[buffer_count] {};
|
|
||||||
|
|
||||||
bool m_thread_should_die { false };
|
|
||||||
BAN::Atomic<bool> m_thread_is_dead { true };
|
|
||||||
ThreadBlocker m_thread_blocker;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,11 +60,7 @@ namespace Kernel
|
||||||
virtual dev_t rdev() const override { return m_rdev; }
|
virtual dev_t rdev() const override { return m_rdev; }
|
||||||
virtual BAN::StringView name() const override { return m_name; }
|
virtual BAN::StringView name() const override { return m_name; }
|
||||||
|
|
||||||
BAN::ErrorOr<void> send_bytes(BAN::MACAddress destination, EtherType protocol, BAN::ConstByteSpan payload)
|
virtual BAN::ErrorOr<void> send_bytes(BAN::MACAddress destination, EtherType protocol, BAN::ConstByteSpan) = 0;
|
||||||
{
|
|
||||||
return send_bytes(destination, protocol, { &payload, 1 });
|
|
||||||
}
|
|
||||||
virtual BAN::ErrorOr<void> send_bytes(BAN::MACAddress destination, EtherType protocol, BAN::Span<const BAN::ConstByteSpan> payload) = 0;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Type m_type;
|
const Type m_type;
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ namespace Kernel
|
||||||
BAN::IPv4Address src_ipv4 { 0 };
|
BAN::IPv4Address src_ipv4 { 0 };
|
||||||
BAN::IPv4Address dst_ipv4 { 0 };
|
BAN::IPv4Address dst_ipv4 { 0 };
|
||||||
BAN::NetworkEndian<uint16_t> protocol { 0 };
|
BAN::NetworkEndian<uint16_t> protocol { 0 };
|
||||||
BAN::NetworkEndian<uint16_t> length { 0 };
|
BAN::NetworkEndian<uint16_t> extra { 0 };
|
||||||
};
|
};
|
||||||
static_assert(sizeof(PseudoHeader) == 12);
|
static_assert(sizeof(PseudoHeader) == 12);
|
||||||
|
|
||||||
|
|
@ -36,7 +36,6 @@ namespace Kernel
|
||||||
NetworkLayer() = default;
|
NetworkLayer() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
uint16_t calculate_internet_checksum(BAN::ConstByteSpan buffer);
|
uint16_t calculate_internet_checksum(BAN::ConstByteSpan packet, const PseudoHeader& pseudo_header);
|
||||||
uint16_t calculate_internet_checksum(BAN::Span<const BAN::ConstByteSpan> buffers);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ namespace Kernel
|
||||||
BAN::ErrorOr<BAN::RefPtr<NetworkInterface>> interface(const sockaddr* target, socklen_t target_len);
|
BAN::ErrorOr<BAN::RefPtr<NetworkInterface>> interface(const sockaddr* target, socklen_t target_len);
|
||||||
|
|
||||||
virtual size_t protocol_header_size() const = 0;
|
virtual size_t protocol_header_size() const = 0;
|
||||||
virtual void get_protocol_header(BAN::ByteSpan header, BAN::ConstByteSpan payload, uint16_t dst_port, PseudoHeader) = 0;
|
virtual void add_protocol_header(BAN::ByteSpan packet, uint16_t dst_port, PseudoHeader) = 0;
|
||||||
virtual NetworkProtocol protocol() const = 0;
|
virtual NetworkProtocol protocol() const = 0;
|
||||||
|
|
||||||
virtual void receive_packet(BAN::ConstByteSpan, const sockaddr* sender, socklen_t sender_len) = 0;
|
virtual void receive_packet(BAN::ConstByteSpan, const sockaddr* sender, socklen_t sender_len) = 0;
|
||||||
|
|
|
||||||
|
|
@ -29,11 +29,9 @@ namespace Kernel
|
||||||
: NetworkInterface(Type::Ethernet)
|
: NetworkInterface(Type::Ethernet)
|
||||||
, m_pci_device(pci_device)
|
, m_pci_device(pci_device)
|
||||||
{ }
|
{ }
|
||||||
~RTL8169();
|
|
||||||
|
|
||||||
BAN::ErrorOr<void> initialize();
|
BAN::ErrorOr<void> initialize();
|
||||||
|
|
||||||
virtual BAN::ErrorOr<void> send_bytes(BAN::MACAddress destination, EtherType protocol, BAN::Span<const BAN::ConstByteSpan>) override;
|
virtual BAN::ErrorOr<void> send_bytes(BAN::MACAddress destination, EtherType protocol, BAN::ConstByteSpan) override;
|
||||||
|
|
||||||
virtual bool can_read_impl() const override { return false; }
|
virtual bool can_read_impl() const override { return false; }
|
||||||
virtual bool can_write_impl() const override { return false; }
|
virtual bool can_write_impl() const override { return false; }
|
||||||
|
|
@ -49,7 +47,7 @@ namespace Kernel
|
||||||
void enable_link();
|
void enable_link();
|
||||||
BAN::ErrorOr<void> enable_interrupt();
|
BAN::ErrorOr<void> enable_interrupt();
|
||||||
|
|
||||||
void receive_thread();
|
void handle_receive();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
PCI::Device& m_pci_device;
|
PCI::Device& m_pci_device;
|
||||||
|
|
@ -65,9 +63,6 @@ namespace Kernel
|
||||||
BAN::UniqPtr<DMARegion> m_tx_descriptor_region;
|
BAN::UniqPtr<DMARegion> m_tx_descriptor_region;
|
||||||
|
|
||||||
SpinLock m_lock;
|
SpinLock m_lock;
|
||||||
|
|
||||||
bool m_thread_should_die { false };
|
|
||||||
BAN::Atomic<bool> m_thread_is_dead { true };
|
|
||||||
ThreadBlocker m_thread_blocker;
|
ThreadBlocker m_thread_blocker;
|
||||||
|
|
||||||
uint32_t m_rx_current { 0 };
|
uint32_t m_rx_current { 0 };
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
#include <BAN/Endianness.h>
|
#include <BAN/Endianness.h>
|
||||||
#include <BAN/Queue.h>
|
#include <BAN/Queue.h>
|
||||||
#include <kernel/Lock/Mutex.h>
|
#include <kernel/Lock/Mutex.h>
|
||||||
#include <kernel/Memory/ByteRingBuffer.h>
|
#include <kernel/Memory/VirtualRange.h>
|
||||||
#include <kernel/Networking/NetworkInterface.h>
|
#include <kernel/Networking/NetworkInterface.h>
|
||||||
#include <kernel/Networking/NetworkSocket.h>
|
#include <kernel/Networking/NetworkSocket.h>
|
||||||
#include <kernel/Thread.h>
|
#include <kernel/Thread.h>
|
||||||
|
|
@ -50,30 +50,29 @@ namespace Kernel
|
||||||
static BAN::ErrorOr<BAN::RefPtr<TCPSocket>> create(NetworkLayer&, const Info&);
|
static BAN::ErrorOr<BAN::RefPtr<TCPSocket>> create(NetworkLayer&, const Info&);
|
||||||
~TCPSocket();
|
~TCPSocket();
|
||||||
|
|
||||||
NetworkProtocol protocol() const override { return NetworkProtocol::TCP; }
|
virtual NetworkProtocol protocol() const override { return NetworkProtocol::TCP; }
|
||||||
|
|
||||||
size_t protocol_header_size() const override { return sizeof(TCPHeader) + m_tcp_options_bytes; }
|
virtual size_t protocol_header_size() const override { return sizeof(TCPHeader) + m_tcp_options_bytes; }
|
||||||
void get_protocol_header(BAN::ByteSpan header, BAN::ConstByteSpan payload, uint16_t dst_port, PseudoHeader) override;
|
virtual void add_protocol_header(BAN::ByteSpan packet, uint16_t dst_port, PseudoHeader) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
BAN::ErrorOr<long> accept_impl(sockaddr*, socklen_t*, int) override;
|
virtual BAN::ErrorOr<long> accept_impl(sockaddr*, socklen_t*, int) override;
|
||||||
BAN::ErrorOr<void> connect_impl(const sockaddr*, socklen_t) override;
|
virtual BAN::ErrorOr<void> connect_impl(const sockaddr*, socklen_t) override;
|
||||||
BAN::ErrorOr<void> listen_impl(int) override;
|
virtual BAN::ErrorOr<void> listen_impl(int) override;
|
||||||
BAN::ErrorOr<void> bind_impl(const sockaddr*, socklen_t) override;
|
virtual BAN::ErrorOr<void> bind_impl(const sockaddr*, socklen_t) override;
|
||||||
BAN::ErrorOr<size_t> recvmsg_impl(msghdr& message, int flags) override;
|
virtual BAN::ErrorOr<size_t> recvmsg_impl(msghdr& message, int flags) override;
|
||||||
BAN::ErrorOr<size_t> sendmsg_impl(const msghdr& message, int flags) override;
|
virtual BAN::ErrorOr<size_t> sendmsg_impl(const msghdr& message, int flags) override;
|
||||||
BAN::ErrorOr<void> getpeername_impl(sockaddr*, socklen_t*) override;
|
virtual BAN::ErrorOr<void> getpeername_impl(sockaddr*, socklen_t*) override;
|
||||||
BAN::ErrorOr<void> getsockopt_impl(int, int, void*, socklen_t*) override;
|
virtual BAN::ErrorOr<void> getsockopt_impl(int, int, void*, socklen_t*) override;
|
||||||
BAN::ErrorOr<void> setsockopt_impl(int, int, const void*, socklen_t) override;
|
|
||||||
|
|
||||||
BAN::ErrorOr<long> ioctl_impl(int, void*) override;
|
virtual BAN::ErrorOr<long> ioctl_impl(int, void*) override;
|
||||||
|
|
||||||
void receive_packet(BAN::ConstByteSpan, const sockaddr* sender, socklen_t sender_len) override;
|
virtual void receive_packet(BAN::ConstByteSpan, const sockaddr* sender, socklen_t sender_len) override;
|
||||||
|
|
||||||
bool can_read_impl() const override;
|
virtual bool can_read_impl() const override;
|
||||||
bool can_write_impl() const override;
|
virtual bool can_write_impl() const override;
|
||||||
bool has_error_impl() const override { return false; }
|
virtual bool has_error_impl() const override { return false; }
|
||||||
bool has_hungup_impl() const override;
|
virtual bool has_hungup_impl() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class State
|
enum class State
|
||||||
|
|
@ -97,8 +96,9 @@ namespace Kernel
|
||||||
|
|
||||||
bool has_ghost_byte { false };
|
bool has_ghost_byte { false };
|
||||||
|
|
||||||
|
uint32_t data_size { 0 }; // number of bytes in this buffer
|
||||||
uint8_t scale_shift { 0 }; // window scale
|
uint8_t scale_shift { 0 }; // window scale
|
||||||
BAN::UniqPtr<ByteRingBuffer> buffer;
|
BAN::UniqPtr<VirtualRange> buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SendWindowInfo
|
struct SendWindowInfo
|
||||||
|
|
@ -115,10 +115,10 @@ namespace Kernel
|
||||||
uint64_t last_send_ms { 0 }; // last send time, used for retransmission timeout
|
uint64_t last_send_ms { 0 }; // last send time, used for retransmission timeout
|
||||||
|
|
||||||
bool has_ghost_byte { false };
|
bool has_ghost_byte { false };
|
||||||
bool had_zero_window { false };
|
|
||||||
|
|
||||||
|
uint32_t data_size { 0 }; // number of bytes in this buffer
|
||||||
uint32_t sent_size { 0 }; // number of bytes in this buffer that have been sent
|
uint32_t sent_size { 0 }; // number of bytes in this buffer that have been sent
|
||||||
BAN::UniqPtr<ByteRingBuffer> buffer;
|
BAN::UniqPtr<VirtualRange> buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ConnectionInfo
|
struct ConnectionInfo
|
||||||
|
|
@ -132,8 +132,6 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
ConnectionInfo target;
|
ConnectionInfo target;
|
||||||
uint32_t target_start_seq;
|
uint32_t target_start_seq;
|
||||||
uint16_t maximum_seqment_size;
|
|
||||||
uint8_t window_scale;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ListenKey
|
struct ListenKey
|
||||||
|
|
@ -168,17 +166,8 @@ namespace Kernel
|
||||||
State m_next_state { State::Closed };
|
State m_next_state { State::Closed };
|
||||||
uint8_t m_next_flags { 0 };
|
uint8_t m_next_flags { 0 };
|
||||||
|
|
||||||
size_t m_last_sent_window_size { 0 };
|
|
||||||
|
|
||||||
Thread* m_thread { nullptr };
|
Thread* m_thread { nullptr };
|
||||||
|
|
||||||
// TODO: actually support these
|
|
||||||
bool m_keep_alive { false };
|
|
||||||
bool m_no_delay { false };
|
|
||||||
|
|
||||||
bool m_should_send_zero_window { false };
|
|
||||||
bool m_should_send_window_update { false };
|
|
||||||
|
|
||||||
uint64_t m_time_wait_start_ms { 0 };
|
uint64_t m_time_wait_start_ms { 0 };
|
||||||
|
|
||||||
ThreadBlocker m_thread_blocker;
|
ThreadBlocker m_thread_blocker;
|
||||||
|
|
|
||||||
|
|
@ -25,28 +25,27 @@ namespace Kernel
|
||||||
public:
|
public:
|
||||||
static BAN::ErrorOr<BAN::RefPtr<UDPSocket>> create(NetworkLayer&, const Socket::Info&);
|
static BAN::ErrorOr<BAN::RefPtr<UDPSocket>> create(NetworkLayer&, const Socket::Info&);
|
||||||
|
|
||||||
NetworkProtocol protocol() const override { return NetworkProtocol::UDP; }
|
virtual NetworkProtocol protocol() const override { return NetworkProtocol::UDP; }
|
||||||
|
|
||||||
size_t protocol_header_size() const override { return sizeof(UDPHeader); }
|
virtual size_t protocol_header_size() const override { return sizeof(UDPHeader); }
|
||||||
void get_protocol_header(BAN::ByteSpan header, BAN::ConstByteSpan payload, uint16_t dst_port, PseudoHeader) override;
|
virtual void add_protocol_header(BAN::ByteSpan packet, uint16_t dst_port, PseudoHeader) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void receive_packet(BAN::ConstByteSpan, const sockaddr* sender, socklen_t sender_len) override;
|
virtual void receive_packet(BAN::ConstByteSpan, const sockaddr* sender, socklen_t sender_len) override;
|
||||||
|
|
||||||
BAN::ErrorOr<void> connect_impl(const sockaddr*, socklen_t) override;
|
virtual BAN::ErrorOr<void> connect_impl(const sockaddr*, socklen_t) override;
|
||||||
BAN::ErrorOr<void> bind_impl(const sockaddr* address, socklen_t address_len) override;
|
virtual BAN::ErrorOr<void> bind_impl(const sockaddr* address, socklen_t address_len) override;
|
||||||
BAN::ErrorOr<size_t> recvmsg_impl(msghdr& message, int flags) override;
|
virtual BAN::ErrorOr<size_t> recvmsg_impl(msghdr& message, int flags) override;
|
||||||
BAN::ErrorOr<size_t> sendmsg_impl(const msghdr& message, int flags) override;
|
virtual BAN::ErrorOr<size_t> sendmsg_impl(const msghdr& message, int flags) override;
|
||||||
BAN::ErrorOr<void> getpeername_impl(sockaddr*, socklen_t*) override { return BAN::Error::from_errno(ENOTCONN); }
|
virtual BAN::ErrorOr<void> getpeername_impl(sockaddr*, socklen_t*) override { return BAN::Error::from_errno(ENOTCONN); }
|
||||||
BAN::ErrorOr<void> getsockopt_impl(int, int, void*, socklen_t*) override;
|
virtual BAN::ErrorOr<void> getsockopt_impl(int, int, void*, socklen_t*) override;
|
||||||
BAN::ErrorOr<void> setsockopt_impl(int, int, const void*, socklen_t) override;
|
|
||||||
|
|
||||||
BAN::ErrorOr<long> ioctl_impl(int, void*) override;
|
virtual BAN::ErrorOr<long> ioctl_impl(int, void*) override;
|
||||||
|
|
||||||
bool can_read_impl() const override { return !m_packets.empty(); }
|
virtual bool can_read_impl() const override { return !m_packets.empty(); }
|
||||||
bool can_write_impl() const override { return true; }
|
virtual bool can_write_impl() const override { return true; }
|
||||||
bool has_error_impl() const override { return false; }
|
virtual bool has_error_impl() const override { return false; }
|
||||||
bool has_hungup_impl() const override { return false; }
|
virtual bool has_hungup_impl() const override { return false; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UDPSocket(NetworkLayer&, const Socket::Info&);
|
UDPSocket(NetworkLayer&, const Socket::Info&);
|
||||||
|
|
|
||||||
|
|
@ -147,8 +147,6 @@ namespace Kernel
|
||||||
BAN::ErrorOr<long> sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event* event);
|
BAN::ErrorOr<long> sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event* event);
|
||||||
BAN::ErrorOr<long> sys_epoll_pwait2(int epfd, struct epoll_event* events, int maxevents, const struct timespec* timeout, const sigset_t* sigmask);
|
BAN::ErrorOr<long> sys_epoll_pwait2(int epfd, struct epoll_event* events, int maxevents, const struct timespec* timeout, const sigset_t* sigmask);
|
||||||
|
|
||||||
BAN::ErrorOr<long> sys_eventfd(unsigned int initval_hi, int flags);
|
|
||||||
|
|
||||||
BAN::ErrorOr<long> sys_pipe(int fildes[2]);
|
BAN::ErrorOr<long> sys_pipe(int fildes[2]);
|
||||||
BAN::ErrorOr<long> sys_dup2(int fildes, int fildes2);
|
BAN::ErrorOr<long> sys_dup2(int fildes, int fildes2);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
#include <BAN/Array.h>
|
#include <BAN/Array.h>
|
||||||
#include <kernel/Device/Device.h>
|
#include <kernel/Device/Device.h>
|
||||||
#include <kernel/Lock/SpinLock.h>
|
#include <kernel/Lock/SpinLock.h>
|
||||||
#include <kernel/Memory/ByteRingBuffer.h>
|
|
||||||
#include <kernel/Terminal/TerminalDriver.h>
|
#include <kernel/Terminal/TerminalDriver.h>
|
||||||
#include <kernel/ThreadBlocker.h>
|
#include <kernel/ThreadBlocker.h>
|
||||||
#include <LibInput/KeyEvent.h>
|
#include <LibInput/KeyEvent.h>
|
||||||
|
|
@ -103,7 +102,8 @@ namespace Kernel
|
||||||
|
|
||||||
struct Buffer
|
struct Buffer
|
||||||
{
|
{
|
||||||
BAN::UniqPtr<ByteRingBuffer> buffer;
|
BAN::Array<uint8_t, 1024> buffer;
|
||||||
|
size_t bytes { 0 };
|
||||||
bool flush { false };
|
bool flush { false };
|
||||||
ThreadBlocker thread_blocker;
|
ThreadBlocker thread_blocker;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -335,8 +335,6 @@ namespace Debug
|
||||||
|
|
||||||
void print_prefix(const char* file, int line)
|
void print_prefix(const char* file, int line)
|
||||||
{
|
{
|
||||||
if (file[0] == '.' && file[1] == '/')
|
|
||||||
file += 2;
|
|
||||||
auto ms_since_boot = Kernel::SystemTimer::is_initialized() ? Kernel::SystemTimer::get().ms_since_boot() : 0;
|
auto ms_since_boot = Kernel::SystemTimer::is_initialized() ? Kernel::SystemTimer::get().ms_since_boot() : 0;
|
||||||
BAN::Formatter::print(Debug::putchar, "[{5}.{3}] {}:{}: ", ms_since_boot / 1000, ms_since_boot % 1000, file, line);
|
BAN::Formatter::print(Debug::putchar, "[{5}.{3}] {}:{}: ", ms_since_boot / 1000, ms_since_boot % 1000, file, line);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,10 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
auto ms_since_boot = SystemTimer::get().ms_since_boot();
|
auto ms_since_boot = SystemTimer::get().ms_since_boot();
|
||||||
SpinLockGuard _(Debug::s_debug_lock);
|
SpinLockGuard _(Debug::s_debug_lock);
|
||||||
BAN::Formatter::print(Debug::putchar, "[{5}.{3}] {}:{} {}: ",
|
BAN::Formatter::print(Debug::putchar, "[{5}.{3}] {} {}: ",
|
||||||
ms_since_boot / 1000,
|
ms_since_boot / 1000,
|
||||||
ms_since_boot % 1000,
|
ms_since_boot % 1000,
|
||||||
Kernel::Process::current().pid(),
|
Kernel::Process::current().pid(),
|
||||||
Thread::current().tid(),
|
|
||||||
Kernel::Process::current().name()
|
Kernel::Process::current().name()
|
||||||
);
|
);
|
||||||
for (size_t i = 0; i < buffer.size(); i++)
|
for (size_t i = 0; i < buffer.size(); i++)
|
||||||
|
|
|
||||||
|
|
@ -209,7 +209,7 @@ namespace Kernel
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
SpinLockGuardAsMutex smutex(guard);
|
SpinLockGuardAsMutex smutex(guard);
|
||||||
TRY(Thread::current().block_or_eintr_or_waketime_ns(m_thread_blocker, waketime_ns, false, &smutex));
|
TRY(Thread::current().block_or_eintr_or_timeout_ns(m_thread_blocker, waketime_ns - current_ns, false, &smutex));
|
||||||
}
|
}
|
||||||
|
|
||||||
return event_count;
|
return event_count;
|
||||||
|
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
#include <kernel/FS/EventFD.h>
|
|
||||||
|
|
||||||
#include <sys/epoll.h>
|
|
||||||
|
|
||||||
namespace Kernel
|
|
||||||
{
|
|
||||||
|
|
||||||
BAN::ErrorOr<BAN::RefPtr<Inode>> EventFD::create(uint64_t initval, bool semaphore)
|
|
||||||
{
|
|
||||||
auto* eventfd_ptr = new EventFD(initval, semaphore);
|
|
||||||
if (eventfd_ptr == nullptr)
|
|
||||||
return BAN::Error::from_errno(ENOMEM);
|
|
||||||
return BAN::RefPtr<Inode>(BAN::RefPtr<EventFD>::adopt(eventfd_ptr));
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::ErrorOr<size_t> EventFD::read_impl(off_t, BAN::ByteSpan buffer)
|
|
||||||
{
|
|
||||||
if (buffer.size() < sizeof(uint64_t))
|
|
||||||
return BAN::Error::from_errno(EINVAL);
|
|
||||||
|
|
||||||
while (m_value == 0)
|
|
||||||
TRY(Thread::current().block_or_eintr_indefinite(m_thread_blocker, &m_mutex));
|
|
||||||
|
|
||||||
const uint64_t read_value = m_is_semaphore ? 1 : m_value;
|
|
||||||
m_value -= read_value;
|
|
||||||
|
|
||||||
buffer.as<uint64_t>() = read_value;
|
|
||||||
|
|
||||||
epoll_notify(EPOLLOUT);
|
|
||||||
|
|
||||||
return sizeof(uint64_t);
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::ErrorOr<size_t> EventFD::write_impl(off_t, BAN::ConstByteSpan buffer)
|
|
||||||
{
|
|
||||||
if (buffer.size() < sizeof(uint64_t))
|
|
||||||
return BAN::Error::from_errno(EINVAL);
|
|
||||||
|
|
||||||
const uint64_t write_value = buffer.as<const uint64_t>();
|
|
||||||
if (write_value == UINT64_MAX)
|
|
||||||
return BAN::Error::from_errno(EINVAL);
|
|
||||||
|
|
||||||
while (m_value + write_value < m_value)
|
|
||||||
TRY(Thread::current().block_or_eintr_indefinite(m_thread_blocker, &m_mutex));
|
|
||||||
|
|
||||||
m_value += write_value;
|
|
||||||
|
|
||||||
if (m_value > 0)
|
|
||||||
epoll_notify(EPOLLIN);
|
|
||||||
|
|
||||||
return sizeof(uint64_t);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -9,16 +9,12 @@
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
{
|
{
|
||||||
|
|
||||||
static constexpr size_t s_pipe_buffer_size = 0x10000;
|
|
||||||
|
|
||||||
BAN::ErrorOr<BAN::RefPtr<Inode>> Pipe::create(const Credentials& credentials)
|
BAN::ErrorOr<BAN::RefPtr<Inode>> Pipe::create(const Credentials& credentials)
|
||||||
{
|
{
|
||||||
auto* pipe_ptr = new Pipe(credentials);
|
Pipe* pipe = new Pipe(credentials);
|
||||||
if (pipe_ptr == nullptr)
|
if (pipe == nullptr)
|
||||||
return BAN::Error::from_errno(ENOMEM);
|
return BAN::Error::from_errno(ENOMEM);
|
||||||
auto pipe = BAN::RefPtr<Pipe>::adopt(pipe_ptr);
|
return BAN::RefPtr<Inode>::adopt(pipe);
|
||||||
pipe->m_buffer = TRY(ByteRingBuffer::create(s_pipe_buffer_size));
|
|
||||||
return BAN::RefPtr<Inode>(pipe);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Pipe::Pipe(const Credentials& credentials)
|
Pipe::Pipe(const Credentials& credentials)
|
||||||
|
|
@ -73,16 +69,27 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<size_t> Pipe::read_impl(off_t, BAN::ByteSpan buffer)
|
BAN::ErrorOr<size_t> Pipe::read_impl(off_t, BAN::ByteSpan buffer)
|
||||||
{
|
{
|
||||||
while (m_buffer->empty())
|
while (m_buffer_size == 0)
|
||||||
{
|
{
|
||||||
if (m_writing_count == 0)
|
if (m_writing_count == 0)
|
||||||
return 0;
|
return 0;
|
||||||
TRY(Thread::current().block_or_eintr_indefinite(m_thread_blocker, &m_mutex));
|
TRY(Thread::current().block_or_eintr_indefinite(m_thread_blocker, &m_mutex));
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t to_copy = BAN::Math::min<size_t>(buffer.size(), m_buffer->size());
|
const size_t to_copy = BAN::Math::min<size_t>(buffer.size(), m_buffer_size);
|
||||||
memcpy(buffer.data(), m_buffer->get_data().data(), to_copy);
|
|
||||||
m_buffer->pop(to_copy);
|
if (m_buffer_tail + to_copy <= m_buffer.size())
|
||||||
|
memcpy(buffer.data(), m_buffer.data() + m_buffer_tail, to_copy);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const size_t before_wrap = m_buffer.size() - m_buffer_tail;
|
||||||
|
const size_t after_wrap = to_copy - before_wrap;
|
||||||
|
memcpy(buffer.data(), m_buffer.data() + m_buffer_tail, before_wrap);
|
||||||
|
memcpy(buffer.data() + before_wrap, m_buffer.data(), after_wrap);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_buffer_tail = (m_buffer_tail + to_copy) % m_buffer.size();
|
||||||
|
m_buffer_size -= to_copy;
|
||||||
|
|
||||||
m_atime = SystemTimer::get().real_time();
|
m_atime = SystemTimer::get().real_time();
|
||||||
|
|
||||||
|
|
@ -95,7 +102,7 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<size_t> Pipe::write_impl(off_t, BAN::ConstByteSpan buffer)
|
BAN::ErrorOr<size_t> Pipe::write_impl(off_t, BAN::ConstByteSpan buffer)
|
||||||
{
|
{
|
||||||
while (m_buffer->full())
|
while (m_buffer_size >= m_buffer.size())
|
||||||
{
|
{
|
||||||
if (m_reading_count == 0)
|
if (m_reading_count == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -105,8 +112,20 @@ namespace Kernel
|
||||||
TRY(Thread::current().block_or_eintr_indefinite(m_thread_blocker, &m_mutex));
|
TRY(Thread::current().block_or_eintr_indefinite(m_thread_blocker, &m_mutex));
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t to_copy = BAN::Math::min(buffer.size(), m_buffer->free());
|
const size_t to_copy = BAN::Math::min(buffer.size(), m_buffer.size() - m_buffer_size);
|
||||||
m_buffer->push(buffer.slice(0, to_copy));
|
const size_t buffer_head = (m_buffer_tail + m_buffer_size) % m_buffer.size();
|
||||||
|
|
||||||
|
if (buffer_head + to_copy <= m_buffer.size())
|
||||||
|
memcpy(m_buffer.data() + buffer_head, buffer.data(), to_copy);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const size_t before_wrap = m_buffer.size() - buffer_head;
|
||||||
|
const size_t after_wrap = to_copy - before_wrap;
|
||||||
|
memcpy(m_buffer.data() + buffer_head, buffer.data(), before_wrap);
|
||||||
|
memcpy(m_buffer.data(), buffer.data() + before_wrap, after_wrap);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_buffer_size += to_copy;
|
||||||
|
|
||||||
timespec current_time = SystemTimer::get().real_time();
|
timespec current_time = SystemTimer::get().real_time();
|
||||||
m_mtime = current_time;
|
m_mtime = current_time;
|
||||||
|
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
#include <kernel/Memory/ByteRingBuffer.h>
|
|
||||||
#include <kernel/Memory/Heap.h>
|
|
||||||
#include <kernel/Memory/PageTable.h>
|
|
||||||
|
|
||||||
namespace Kernel
|
|
||||||
{
|
|
||||||
|
|
||||||
BAN::ErrorOr<BAN::UniqPtr<ByteRingBuffer>> ByteRingBuffer::create(size_t size)
|
|
||||||
{
|
|
||||||
ASSERT(size % PAGE_SIZE == 0);
|
|
||||||
|
|
||||||
const size_t page_count = size / PAGE_SIZE;
|
|
||||||
|
|
||||||
auto* buffer_ptr = new ByteRingBuffer(size);
|
|
||||||
if (buffer_ptr == nullptr)
|
|
||||||
return BAN::Error::from_errno(ENOMEM);
|
|
||||||
auto buffer = BAN::UniqPtr<ByteRingBuffer>::adopt(buffer_ptr);
|
|
||||||
|
|
||||||
buffer->m_vaddr = PageTable::kernel().reserve_free_contiguous_pages(page_count * 2, KERNEL_OFFSET);
|
|
||||||
if (buffer->m_vaddr == 0)
|
|
||||||
return BAN::Error::from_errno(ENOMEM);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < page_count; i++)
|
|
||||||
{
|
|
||||||
const paddr_t paddr = Heap::get().take_free_page();
|
|
||||||
if (paddr == 0)
|
|
||||||
return BAN::Error::from_errno(ENOMEM);
|
|
||||||
PageTable::kernel().map_page_at(paddr, buffer->m_vaddr + i * PAGE_SIZE, PageTable::ReadWrite | PageTable::Present);
|
|
||||||
PageTable::kernel().map_page_at(paddr, buffer->m_vaddr + size + i * PAGE_SIZE, PageTable::ReadWrite | PageTable::Present);
|
|
||||||
}
|
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
ByteRingBuffer::~ByteRingBuffer()
|
|
||||||
{
|
|
||||||
if (m_vaddr == 0)
|
|
||||||
return;
|
|
||||||
for (size_t i = 0; i < m_capacity / PAGE_SIZE; i++)
|
|
||||||
{
|
|
||||||
const paddr_t paddr = PageTable::kernel().physical_address_of(m_vaddr + i * PAGE_SIZE);
|
|
||||||
if (paddr == 0)
|
|
||||||
break;
|
|
||||||
Heap::get().release_page(paddr);
|
|
||||||
}
|
|
||||||
PageTable::kernel().unmap_range(m_vaddr, m_capacity * 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -17,7 +17,27 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<BAN::UniqPtr<ARPTable>> ARPTable::create()
|
BAN::ErrorOr<BAN::UniqPtr<ARPTable>> ARPTable::create()
|
||||||
{
|
{
|
||||||
return TRY(BAN::UniqPtr<ARPTable>::create());
|
auto arp_table = TRY(BAN::UniqPtr<ARPTable>::create());
|
||||||
|
arp_table->m_thread = TRY(Thread::create_kernel(
|
||||||
|
[](void* arp_table_ptr)
|
||||||
|
{
|
||||||
|
auto& arp_table = *reinterpret_cast<ARPTable*>(arp_table_ptr);
|
||||||
|
arp_table.packet_handle_task();
|
||||||
|
}, arp_table.ptr()
|
||||||
|
));
|
||||||
|
TRY(Processor::scheduler().add_thread(arp_table->m_thread));
|
||||||
|
return arp_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
ARPTable::ARPTable()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ARPTable::~ARPTable()
|
||||||
|
{
|
||||||
|
if (m_thread)
|
||||||
|
m_thread->add_signal(SIGKILL, {});
|
||||||
|
m_thread = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<BAN::MACAddress> ARPTable::get_mac_from_ipv4(NetworkInterface& interface, BAN::IPv4Address ipv4_address)
|
BAN::ErrorOr<BAN::MACAddress> ARPTable::get_mac_from_ipv4(NetworkInterface& interface, BAN::IPv4Address ipv4_address)
|
||||||
|
|
@ -44,7 +64,7 @@ namespace Kernel
|
||||||
ipv4_address = interface.get_gateway();
|
ipv4_address = interface.get_gateway();
|
||||||
|
|
||||||
{
|
{
|
||||||
SpinLockGuard _(m_arp_table_lock);
|
SpinLockGuard _(m_table_lock);
|
||||||
auto it = m_arp_table.find(ipv4_address);
|
auto it = m_arp_table.find(ipv4_address);
|
||||||
if (it != m_arp_table.end())
|
if (it != m_arp_table.end())
|
||||||
return it->value;
|
return it->value;
|
||||||
|
|
@ -67,7 +87,7 @@ namespace Kernel
|
||||||
while (SystemTimer::get().ms_since_boot() < timeout)
|
while (SystemTimer::get().ms_since_boot() < timeout)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
SpinLockGuard _(m_arp_table_lock);
|
SpinLockGuard _(m_table_lock);
|
||||||
auto it = m_arp_table.find(ipv4_address);
|
auto it = m_arp_table.find(ipv4_address);
|
||||||
if (it != m_arp_table.end())
|
if (it != m_arp_table.end())
|
||||||
return it->value;
|
return it->value;
|
||||||
|
|
@ -78,16 +98,8 @@ namespace Kernel
|
||||||
return BAN::Error::from_errno(ETIMEDOUT);
|
return BAN::Error::from_errno(ETIMEDOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<void> ARPTable::handle_arp_packet(NetworkInterface& interface, BAN::ConstByteSpan buffer)
|
BAN::ErrorOr<void> ARPTable::handle_arp_packet(NetworkInterface& interface, const ARPPacket& packet)
|
||||||
{
|
{
|
||||||
if (buffer.size() < sizeof(ARPPacket))
|
|
||||||
{
|
|
||||||
dwarnln_if(DEBUG_ARP, "Too small ARP packet");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto& packet = buffer.as<const ARPPacket>();
|
|
||||||
|
|
||||||
if (packet.ptype != EtherType::IPv4)
|
if (packet.ptype != EtherType::IPv4)
|
||||||
{
|
{
|
||||||
dprintln("Non IPv4 arp packet?");
|
dprintln("Non IPv4 arp packet?");
|
||||||
|
|
@ -100,24 +112,23 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
if (packet.tpa == interface.get_ipv4_address())
|
if (packet.tpa == interface.get_ipv4_address())
|
||||||
{
|
{
|
||||||
const ARPPacket arp_reply {
|
ARPPacket arp_reply;
|
||||||
.htype = 0x0001,
|
arp_reply.htype = 0x0001;
|
||||||
.ptype = EtherType::IPv4,
|
arp_reply.ptype = EtherType::IPv4;
|
||||||
.hlen = 0x06,
|
arp_reply.hlen = 0x06;
|
||||||
.plen = 0x04,
|
arp_reply.plen = 0x04;
|
||||||
.oper = ARPOperation::Reply,
|
arp_reply.oper = ARPOperation::Reply;
|
||||||
.sha = interface.get_mac_address(),
|
arp_reply.sha = interface.get_mac_address();
|
||||||
.spa = interface.get_ipv4_address(),
|
arp_reply.spa = interface.get_ipv4_address();
|
||||||
.tha = packet.sha,
|
arp_reply.tha = packet.sha;
|
||||||
.tpa = packet.spa,
|
arp_reply.tpa = packet.spa;
|
||||||
};
|
|
||||||
TRY(interface.send_bytes(packet.sha, EtherType::ARP, BAN::ConstByteSpan::from(arp_reply)));
|
TRY(interface.send_bytes(packet.sha, EtherType::ARP, BAN::ConstByteSpan::from(arp_reply)));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ARPOperation::Reply:
|
case ARPOperation::Reply:
|
||||||
{
|
{
|
||||||
SpinLockGuard _(m_arp_table_lock);
|
SpinLockGuard _(m_table_lock);
|
||||||
auto it = m_arp_table.find(packet.spa);
|
auto it = m_arp_table.find(packet.spa);
|
||||||
|
|
||||||
if (it != m_arp_table.end())
|
if (it != m_arp_table.end())
|
||||||
|
|
@ -143,4 +154,48 @@ namespace Kernel
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ARPTable::packet_handle_task()
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
PendingArpPacket pending = ({
|
||||||
|
SpinLockGuard guard(m_pending_lock);
|
||||||
|
while (m_pending_packets.empty())
|
||||||
|
{
|
||||||
|
SpinLockGuardAsMutex smutex(guard);
|
||||||
|
m_pending_thread_blocker.block_indefinite(&smutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto packet = m_pending_packets.front();
|
||||||
|
m_pending_packets.pop();
|
||||||
|
|
||||||
|
packet;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (auto ret = handle_arp_packet(pending.interface, pending.packet); ret.is_error())
|
||||||
|
dwarnln("{}", ret.error());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARPTable::add_arp_packet(NetworkInterface& interface, BAN::ConstByteSpan buffer)
|
||||||
|
{
|
||||||
|
if (buffer.size() < sizeof(ARPPacket))
|
||||||
|
{
|
||||||
|
dwarnln_if(DEBUG_ARP, "ARP packet too small");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto& arp_packet = buffer.as<const ARPPacket>();
|
||||||
|
|
||||||
|
SpinLockGuard _(m_pending_lock);
|
||||||
|
|
||||||
|
if (m_pending_packets.full())
|
||||||
|
{
|
||||||
|
dwarnln_if(DEBUG_ARP, "ARP packet queue full");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pending_packets.push({ .interface = interface, .packet = arp_packet });
|
||||||
|
m_pending_thread_blocker.unblock();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
#include <kernel/IDT.h>
|
#include <kernel/IDT.h>
|
||||||
#include <kernel/InterruptController.h>
|
#include <kernel/InterruptController.h>
|
||||||
#include <kernel/IO.h>
|
#include <kernel/IO.h>
|
||||||
#include <kernel/Lock/SpinLockAsMutex.h>
|
|
||||||
#include <kernel/Memory/PageTable.h>
|
#include <kernel/Memory/PageTable.h>
|
||||||
#include <kernel/MMIO.h>
|
#include <kernel/MMIO.h>
|
||||||
#include <kernel/Networking/E1000/E1000.h>
|
#include <kernel/Networking/E1000/E1000.h>
|
||||||
|
|
@ -58,11 +57,6 @@ namespace Kernel
|
||||||
|
|
||||||
E1000::~E1000()
|
E1000::~E1000()
|
||||||
{
|
{
|
||||||
m_thread_should_die = true;
|
|
||||||
m_thread_blocker.unblock();
|
|
||||||
|
|
||||||
while (!m_thread_is_dead)
|
|
||||||
Processor::yield();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<void> E1000::initialize()
|
BAN::ErrorOr<void> E1000::initialize()
|
||||||
|
|
@ -90,16 +84,6 @@ namespace Kernel
|
||||||
dprintln(" link speed: {} Mbps", speed);
|
dprintln(" link speed: {} Mbps", speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* thread = TRY(Thread::create_kernel([](void* e1000_ptr) {
|
|
||||||
static_cast<E1000*>(e1000_ptr)->receive_thread();
|
|
||||||
}, this));
|
|
||||||
if (auto ret = Processor::scheduler().add_thread(thread); ret.is_error())
|
|
||||||
{
|
|
||||||
delete thread;
|
|
||||||
return ret.release_error();
|
|
||||||
}
|
|
||||||
m_thread_is_dead = false;
|
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -275,8 +259,10 @@ namespace Kernel
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<void> E1000::send_bytes(BAN::MACAddress destination, EtherType protocol, BAN::Span<const BAN::ConstByteSpan> payload)
|
BAN::ErrorOr<void> E1000::send_bytes(BAN::MACAddress destination, EtherType protocol, BAN::ConstByteSpan buffer)
|
||||||
{
|
{
|
||||||
|
ASSERT(buffer.size() + sizeof(EthernetHeader) <= E1000_TX_BUFFER_SIZE);
|
||||||
|
|
||||||
SpinLockGuard _(m_lock);
|
SpinLockGuard _(m_lock);
|
||||||
|
|
||||||
size_t tx_current = read32(REG_TDT) % E1000_TX_DESCRIPTOR_COUNT;
|
size_t tx_current = read32(REG_TDT) % E1000_TX_DESCRIPTOR_COUNT;
|
||||||
|
|
@ -288,38 +274,33 @@ namespace Kernel
|
||||||
ethernet_header.src_mac = get_mac_address();
|
ethernet_header.src_mac = get_mac_address();
|
||||||
ethernet_header.ether_type = protocol;
|
ethernet_header.ether_type = protocol;
|
||||||
|
|
||||||
size_t packet_size = sizeof(EthernetHeader);
|
memcpy(tx_buffer + sizeof(EthernetHeader), buffer.data(), buffer.size());
|
||||||
for (const auto& buffer : payload)
|
|
||||||
{
|
|
||||||
ASSERT(packet_size + buffer.size() < E1000_TX_BUFFER_SIZE);
|
|
||||||
memcpy(tx_buffer + packet_size, buffer.data(), buffer.size());
|
|
||||||
packet_size += buffer.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& descriptor = reinterpret_cast<volatile e1000_tx_desc*>(m_tx_descriptor_region->vaddr())[tx_current];
|
auto& descriptor = reinterpret_cast<volatile e1000_tx_desc*>(m_tx_descriptor_region->vaddr())[tx_current];
|
||||||
descriptor.length = packet_size;
|
descriptor.length = sizeof(EthernetHeader) + buffer.size();
|
||||||
descriptor.status = 0;
|
descriptor.status = 0;
|
||||||
descriptor.cmd = CMD_EOP | CMD_IFCS | CMD_RS;
|
descriptor.cmd = CMD_EOP | CMD_IFCS | CMD_RS;
|
||||||
|
|
||||||
// FIXME: there isnt really any reason to wait for transmission
|
|
||||||
write32(REG_TDT, (tx_current + 1) % E1000_TX_DESCRIPTOR_COUNT);
|
write32(REG_TDT, (tx_current + 1) % E1000_TX_DESCRIPTOR_COUNT);
|
||||||
while (descriptor.status == 0)
|
while (descriptor.status == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
dprintln_if(DEBUG_E1000, "sent {} bytes", packet_size);
|
dprintln_if(DEBUG_E1000, "sent {} bytes", sizeof(EthernetHeader) + buffer.size());
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void E1000::receive_thread()
|
void E1000::handle_irq()
|
||||||
{
|
{
|
||||||
|
const uint32_t icr = read32(REG_ICR);
|
||||||
|
if (!(icr & (ICR_RxQ0 | ICR_RXT0)))
|
||||||
|
return;
|
||||||
|
write32(REG_ICR, icr);
|
||||||
|
|
||||||
SpinLockGuard _(m_lock);
|
SpinLockGuard _(m_lock);
|
||||||
|
|
||||||
while (!m_thread_should_die)
|
for (;;) {
|
||||||
{
|
uint32_t rx_current = (read32(REG_RDT0) + 1) % E1000_RX_DESCRIPTOR_COUNT;
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
const uint32_t rx_current = (read32(REG_RDT0) + 1) % E1000_RX_DESCRIPTOR_COUNT;
|
|
||||||
|
|
||||||
auto& descriptor = reinterpret_cast<volatile e1000_rx_desc*>(m_rx_descriptor_region->vaddr())[rx_current];
|
auto& descriptor = reinterpret_cast<volatile e1000_rx_desc*>(m_rx_descriptor_region->vaddr())[rx_current];
|
||||||
if (!(descriptor.status & 1))
|
if (!(descriptor.status & 1))
|
||||||
|
|
@ -328,36 +309,14 @@ namespace Kernel
|
||||||
|
|
||||||
dprintln_if(DEBUG_E1000, "got {} bytes", (uint16_t)descriptor.length);
|
dprintln_if(DEBUG_E1000, "got {} bytes", (uint16_t)descriptor.length);
|
||||||
|
|
||||||
m_lock.unlock(InterruptState::Enabled);
|
|
||||||
|
|
||||||
NetworkManager::get().on_receive(*this, BAN::ConstByteSpan {
|
NetworkManager::get().on_receive(*this, BAN::ConstByteSpan {
|
||||||
reinterpret_cast<const uint8_t*>(m_rx_buffer_region->vaddr() + rx_current * E1000_RX_BUFFER_SIZE),
|
reinterpret_cast<const uint8_t*>(m_rx_buffer_region->vaddr() + rx_current * E1000_RX_BUFFER_SIZE),
|
||||||
descriptor.length
|
descriptor.length
|
||||||
});
|
});
|
||||||
|
|
||||||
m_lock.lock();
|
|
||||||
|
|
||||||
descriptor.status = 0;
|
descriptor.status = 0;
|
||||||
write32(REG_RDT0, rx_current);
|
write32(REG_RDT0, rx_current);
|
||||||
}
|
}
|
||||||
|
|
||||||
SpinLockAsMutex smutex(m_lock, InterruptState::Enabled);
|
|
||||||
m_thread_blocker.block_indefinite(&smutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_thread_is_dead = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void E1000::handle_irq()
|
|
||||||
{
|
|
||||||
const uint32_t icr = read32(REG_ICR);
|
|
||||||
write32(REG_ICR, icr);
|
|
||||||
|
|
||||||
if (icr & (ICR_RxQ0 | ICR_RXT0))
|
|
||||||
{
|
|
||||||
SpinLockGuard _(m_lock);
|
|
||||||
m_thread_blocker.unblock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,26 +21,50 @@ namespace Kernel
|
||||||
BAN::ErrorOr<BAN::UniqPtr<IPv4Layer>> IPv4Layer::create()
|
BAN::ErrorOr<BAN::UniqPtr<IPv4Layer>> IPv4Layer::create()
|
||||||
{
|
{
|
||||||
auto ipv4_manager = TRY(BAN::UniqPtr<IPv4Layer>::create());
|
auto ipv4_manager = TRY(BAN::UniqPtr<IPv4Layer>::create());
|
||||||
|
ipv4_manager->m_thread = TRY(Thread::create_kernel(
|
||||||
|
[](void* ipv4_manager_ptr)
|
||||||
|
{
|
||||||
|
auto& ipv4_manager = *reinterpret_cast<IPv4Layer*>(ipv4_manager_ptr);
|
||||||
|
ipv4_manager.packet_handle_task();
|
||||||
|
}, ipv4_manager.ptr()
|
||||||
|
));
|
||||||
|
TRY(Processor::scheduler().add_thread(ipv4_manager->m_thread));
|
||||||
|
ipv4_manager->m_pending_packet_buffer = TRY(VirtualRange::create_to_vaddr_range(
|
||||||
|
PageTable::kernel(),
|
||||||
|
KERNEL_OFFSET,
|
||||||
|
~(uintptr_t)0,
|
||||||
|
pending_packet_buffer_size,
|
||||||
|
PageTable::Flags::ReadWrite | PageTable::Flags::Present,
|
||||||
|
true, false
|
||||||
|
));
|
||||||
ipv4_manager->m_arp_table = TRY(ARPTable::create());
|
ipv4_manager->m_arp_table = TRY(ARPTable::create());
|
||||||
return ipv4_manager;
|
return ipv4_manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
static IPv4Header get_ipv4_header(size_t packet_size, BAN::IPv4Address src_ipv4, BAN::IPv4Address dst_ipv4, uint8_t protocol)
|
IPv4Layer::IPv4Layer()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
IPv4Layer::~IPv4Layer()
|
||||||
{
|
{
|
||||||
IPv4Header header {
|
if (m_thread)
|
||||||
.version_IHL = 0x45,
|
m_thread->add_signal(SIGKILL, {});
|
||||||
.DSCP_ECN = 0x00,
|
m_thread = nullptr;
|
||||||
.total_length = packet_size,
|
}
|
||||||
.identification = 1,
|
|
||||||
.flags_frament = 0x00,
|
void IPv4Layer::add_ipv4_header(BAN::ByteSpan packet, BAN::IPv4Address src_ipv4, BAN::IPv4Address dst_ipv4, uint8_t protocol) const
|
||||||
.time_to_live = 0x40,
|
{
|
||||||
.protocol = protocol,
|
auto& header = packet.as<IPv4Header>();
|
||||||
.checksum = 0,
|
header.version_IHL = 0x45;
|
||||||
.src_address = src_ipv4,
|
header.DSCP_ECN = 0x00;
|
||||||
.dst_address = dst_ipv4,
|
header.total_length = packet.size();
|
||||||
};
|
header.identification = 1;
|
||||||
header.checksum = calculate_internet_checksum(BAN::ConstByteSpan::from(header));
|
header.flags_frament = 0x00;
|
||||||
return header;
|
header.time_to_live = 0x40;
|
||||||
|
header.protocol = protocol;
|
||||||
|
header.src_address = src_ipv4;
|
||||||
|
header.dst_address = dst_ipv4;
|
||||||
|
header.checksum = 0;
|
||||||
|
header.checksum = calculate_internet_checksum(BAN::ConstByteSpan::from(header), {});
|
||||||
}
|
}
|
||||||
|
|
||||||
void IPv4Layer::unbind_socket(uint16_t port)
|
void IPv4Layer::unbind_socket(uint16_t port)
|
||||||
|
|
@ -180,7 +204,7 @@ namespace Kernel
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<size_t> IPv4Layer::sendto(NetworkSocket& socket, BAN::ConstByteSpan payload, const sockaddr* address, socklen_t address_len)
|
BAN::ErrorOr<size_t> IPv4Layer::sendto(NetworkSocket& socket, BAN::ConstByteSpan buffer, const sockaddr* address, socklen_t address_len)
|
||||||
{
|
{
|
||||||
if (address->sa_family != AF_INET)
|
if (address->sa_family != AF_INET)
|
||||||
return BAN::Error::from_errno(EINVAL);
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
|
@ -207,63 +231,46 @@ namespace Kernel
|
||||||
|
|
||||||
if (!receiver)
|
if (!receiver)
|
||||||
return BAN::Error::from_errno(EADDRNOTAVAIL);
|
return BAN::Error::from_errno(EADDRNOTAVAIL);
|
||||||
|
TRY(socket.interface(receiver->address(), receiver->address_len()));
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto ipv4_header = get_ipv4_header(
|
BAN::Vector<uint8_t> packet_buffer;
|
||||||
sizeof(IPv4Header) + socket.protocol_header_size() + payload.size(),
|
TRY(packet_buffer.resize(buffer.size() + sizeof(IPv4Header) + socket.protocol_header_size()));
|
||||||
|
auto packet = BAN::ByteSpan { packet_buffer.span() };
|
||||||
|
|
||||||
|
auto pseudo_header = PseudoHeader {
|
||||||
|
.src_ipv4 = interface->get_ipv4_address(),
|
||||||
|
.dst_ipv4 = dst_ipv4,
|
||||||
|
.protocol = socket.protocol()
|
||||||
|
};
|
||||||
|
|
||||||
|
memcpy(
|
||||||
|
packet.slice(sizeof(IPv4Header)).slice(socket.protocol_header_size()).data(),
|
||||||
|
buffer.data(),
|
||||||
|
buffer.size()
|
||||||
|
);
|
||||||
|
socket.add_protocol_header(
|
||||||
|
packet.slice(sizeof(IPv4Header)),
|
||||||
|
dst_port,
|
||||||
|
pseudo_header
|
||||||
|
);
|
||||||
|
add_ipv4_header(
|
||||||
|
packet,
|
||||||
interface->get_ipv4_address(),
|
interface->get_ipv4_address(),
|
||||||
dst_ipv4,
|
dst_ipv4,
|
||||||
socket.protocol()
|
socket.protocol()
|
||||||
);
|
);
|
||||||
|
|
||||||
const auto pseudo_header = PseudoHeader {
|
TRY(interface->send_bytes(dst_mac, EtherType::IPv4, packet));
|
||||||
.src_ipv4 = interface->get_ipv4_address(),
|
|
||||||
.dst_ipv4 = dst_ipv4,
|
|
||||||
.protocol = socket.protocol(),
|
|
||||||
.length = socket.protocol_header_size() + payload.size()
|
|
||||||
};
|
|
||||||
|
|
||||||
uint8_t protocol_header_buffer[32];
|
return buffer.size();
|
||||||
ASSERT(socket.protocol_header_size() < sizeof(protocol_header_buffer));
|
|
||||||
|
|
||||||
auto protocol_header = BAN::ByteSpan::from(protocol_header_buffer).slice(0, socket.protocol_header_size());
|
|
||||||
socket.get_protocol_header(protocol_header, payload, dst_port, pseudo_header);
|
|
||||||
|
|
||||||
BAN::ConstByteSpan buffers[] {
|
|
||||||
BAN::ConstByteSpan::from(ipv4_header),
|
|
||||||
protocol_header,
|
|
||||||
payload,
|
|
||||||
};
|
|
||||||
|
|
||||||
TRY(interface->send_bytes(dst_mac, EtherType::IPv4, { buffers, sizeof(buffers) / sizeof(*buffers) }));
|
|
||||||
|
|
||||||
return payload.size();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<void> IPv4Layer::handle_ipv4_packet(NetworkInterface& interface, BAN::ConstByteSpan packet)
|
BAN::ErrorOr<void> IPv4Layer::handle_ipv4_packet(NetworkInterface& interface, BAN::ByteSpan packet)
|
||||||
{
|
{
|
||||||
if (packet.size() < sizeof(IPv4Header))
|
ASSERT(packet.size() >= sizeof(IPv4Header));
|
||||||
{
|
|
||||||
dwarnln_if(DEBUG_IPV4, "Too small IPv4 packet");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& ipv4_header = packet.as<const IPv4Header>();
|
auto& ipv4_header = packet.as<const IPv4Header>();
|
||||||
if (calculate_internet_checksum(BAN::ConstByteSpan::from(ipv4_header)) != 0)
|
auto ipv4_data = packet.slice(sizeof(IPv4Header));
|
||||||
{
|
|
||||||
dwarnln_if(DEBUG_IPV4, "IPv4 packet checksum failed");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
if (ipv4_header.total_length > packet.size() || ipv4_header.total_length > interface.payload_mtu() || ipv4_header.total_length < sizeof(IPv4Header))
|
|
||||||
{
|
|
||||||
if (ipv4_header.flags_frament & IPv4Flags::DF)
|
|
||||||
dwarnln_if(DEBUG_IPV4, "Invalid IPv4 packet");
|
|
||||||
else
|
|
||||||
dwarnln_if(DEBUG_IPV4, "IPv4 fragmentation not supported");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ipv4_data = packet.slice(0, ipv4_header.total_length).slice(sizeof(IPv4Header));
|
|
||||||
|
|
||||||
auto src_ipv4 = ipv4_header.src_address;
|
auto src_ipv4 = ipv4_header.src_address;
|
||||||
|
|
||||||
|
|
@ -286,33 +293,14 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
auto dst_mac = TRY(m_arp_table->get_mac_from_ipv4(interface, src_ipv4));
|
auto dst_mac = TRY(m_arp_table->get_mac_from_ipv4(interface, src_ipv4));
|
||||||
|
|
||||||
auto send_ipv4_header = get_ipv4_header(
|
auto& reply_icmp_header = ipv4_data.as<ICMPHeader>();
|
||||||
ipv4_data.size(),
|
reply_icmp_header.type = ICMPType::EchoReply;
|
||||||
interface.get_ipv4_address(),
|
reply_icmp_header.checksum = 0;
|
||||||
src_ipv4,
|
reply_icmp_header.checksum = calculate_internet_checksum(ipv4_data, {});
|
||||||
NetworkProtocol::ICMP
|
|
||||||
);
|
|
||||||
|
|
||||||
ICMPHeader send_icmp_header {
|
add_ipv4_header(packet, interface.get_ipv4_address(), src_ipv4, NetworkProtocol::ICMP);
|
||||||
.type = ICMPType::EchoReply,
|
|
||||||
.code = icmp_header.code,
|
|
||||||
.checksum = 0,
|
|
||||||
.rest = icmp_header.rest,
|
|
||||||
};
|
|
||||||
|
|
||||||
auto send_payload = ipv4_data.slice(sizeof(ICMPHeader));
|
|
||||||
|
|
||||||
const BAN::ConstByteSpan send_buffers[] {
|
|
||||||
BAN::ConstByteSpan::from(send_ipv4_header),
|
|
||||||
BAN::ConstByteSpan::from(send_icmp_header),
|
|
||||||
send_payload
|
|
||||||
};
|
|
||||||
auto send_buffers_span = BAN::Span { send_buffers, sizeof(send_buffers) / sizeof(*send_buffers) };
|
|
||||||
|
|
||||||
send_icmp_header.checksum = calculate_internet_checksum(send_buffers_span.slice(1));
|
|
||||||
|
|
||||||
TRY(interface.send_bytes(dst_mac, EtherType::IPv4, send_buffers_span));
|
|
||||||
|
|
||||||
|
TRY(interface.send_bytes(dst_mac, EtherType::IPv4, packet));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ICMPType::DestinationUnreachable:
|
case ICMPType::DestinationUnreachable:
|
||||||
|
|
@ -394,4 +382,80 @@ namespace Kernel
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IPv4Layer::packet_handle_task()
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
PendingIPv4Packet pending = ({
|
||||||
|
SpinLockGuard guard(m_pending_lock);
|
||||||
|
while (m_pending_packets.empty())
|
||||||
|
{
|
||||||
|
SpinLockGuardAsMutex smutex(guard);
|
||||||
|
m_pending_thread_blocker.block_indefinite(&smutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto packet = m_pending_packets.front();
|
||||||
|
m_pending_packets.pop();
|
||||||
|
|
||||||
|
packet;
|
||||||
|
});
|
||||||
|
|
||||||
|
uint8_t* buffer_start = reinterpret_cast<uint8_t*>(m_pending_packet_buffer->vaddr());
|
||||||
|
const size_t ipv4_packet_size = reinterpret_cast<const IPv4Header*>(buffer_start)->total_length;
|
||||||
|
|
||||||
|
if (auto ret = handle_ipv4_packet(pending.interface, BAN::ByteSpan(buffer_start, ipv4_packet_size)); ret.is_error())
|
||||||
|
dwarnln_if(DEBUG_IPV4, "{}", ret.error());
|
||||||
|
|
||||||
|
SpinLockGuard _(m_pending_lock);
|
||||||
|
m_pending_total_size -= ipv4_packet_size;
|
||||||
|
if (m_pending_total_size)
|
||||||
|
memmove(buffer_start, buffer_start + ipv4_packet_size, m_pending_total_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IPv4Layer::add_ipv4_packet(NetworkInterface& interface, BAN::ConstByteSpan buffer)
|
||||||
|
{
|
||||||
|
if (buffer.size() < sizeof(IPv4Header))
|
||||||
|
{
|
||||||
|
dwarnln_if(DEBUG_IPV4, "IPv4 packet too small");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SpinLockGuard _(m_pending_lock);
|
||||||
|
|
||||||
|
if (m_pending_packets.full())
|
||||||
|
{
|
||||||
|
dwarnln_if(DEBUG_IPV4, "IPv4 packet queue full");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_pending_total_size + buffer.size() > m_pending_packet_buffer->size())
|
||||||
|
{
|
||||||
|
dwarnln_if(DEBUG_IPV4, "IPv4 packet queue full");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& ipv4_header = buffer.as<const IPv4Header>();
|
||||||
|
if (calculate_internet_checksum(BAN::ConstByteSpan::from(ipv4_header), {}) != 0)
|
||||||
|
{
|
||||||
|
dwarnln_if(DEBUG_IPV4, "Invalid IPv4 packet");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ipv4_header.total_length > buffer.size() || ipv4_header.total_length > interface.payload_mtu())
|
||||||
|
{
|
||||||
|
if (ipv4_header.flags_frament & IPv4Flags::DF)
|
||||||
|
dwarnln_if(DEBUG_IPV4, "Invalid IPv4 packet");
|
||||||
|
else
|
||||||
|
dwarnln_if(DEBUG_IPV4, "IPv4 fragmentation not supported");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* buffer_start = reinterpret_cast<uint8_t*>(m_pending_packet_buffer->vaddr());
|
||||||
|
memcpy(buffer_start + m_pending_total_size, buffer.data(), ipv4_header.total_length);
|
||||||
|
m_pending_total_size += ipv4_header.total_length;
|
||||||
|
|
||||||
|
m_pending_packets.push({ .interface = interface });
|
||||||
|
m_pending_thread_blocker.unblock();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
#include <kernel/Lock/LockGuard.h>
|
|
||||||
#include <kernel/Networking/Loopback.h>
|
#include <kernel/Networking/Loopback.h>
|
||||||
#include <kernel/Networking/NetworkManager.h>
|
#include <kernel/Networking/NetworkManager.h>
|
||||||
|
|
||||||
|
|
@ -11,121 +10,40 @@ namespace Kernel
|
||||||
if (loopback_ptr == nullptr)
|
if (loopback_ptr == nullptr)
|
||||||
return BAN::Error::from_errno(ENOMEM);
|
return BAN::Error::from_errno(ENOMEM);
|
||||||
auto loopback = BAN::RefPtr<LoopbackInterface>::adopt(loopback_ptr);
|
auto loopback = BAN::RefPtr<LoopbackInterface>::adopt(loopback_ptr);
|
||||||
|
|
||||||
loopback->m_buffer = TRY(VirtualRange::create_to_vaddr_range(
|
loopback->m_buffer = TRY(VirtualRange::create_to_vaddr_range(
|
||||||
PageTable::kernel(),
|
PageTable::kernel(),
|
||||||
KERNEL_OFFSET,
|
KERNEL_OFFSET,
|
||||||
BAN::numeric_limits<vaddr_t>::max(),
|
BAN::numeric_limits<vaddr_t>::max(),
|
||||||
buffer_size * buffer_count,
|
buffer_size,
|
||||||
PageTable::Flags::ReadWrite | PageTable::Flags::Present,
|
PageTable::Flags::ReadWrite | PageTable::Flags::Present,
|
||||||
true, false
|
true, false
|
||||||
));
|
));
|
||||||
|
|
||||||
auto* thread = TRY(Thread::create_kernel([](void* loopback_ptr) {
|
|
||||||
static_cast<LoopbackInterface*>(loopback_ptr)->receive_thread();
|
|
||||||
}, loopback_ptr));
|
|
||||||
if (auto ret = Processor::scheduler().add_thread(thread); ret.is_error())
|
|
||||||
{
|
|
||||||
delete thread;
|
|
||||||
return ret.release_error();
|
|
||||||
}
|
|
||||||
loopback->m_thread_is_dead = false;
|
|
||||||
|
|
||||||
loopback->set_ipv4_address({ 127, 0, 0, 1 });
|
loopback->set_ipv4_address({ 127, 0, 0, 1 });
|
||||||
loopback->set_netmask({ 255, 0, 0, 0 });
|
loopback->set_netmask({ 255, 0, 0, 0 });
|
||||||
|
|
||||||
for (size_t i = 0; i < buffer_count; i++)
|
|
||||||
{
|
|
||||||
loopback->m_descriptors[i] = {
|
|
||||||
.addr = reinterpret_cast<uint8_t*>(loopback->m_buffer->vaddr()) + i * buffer_size,
|
|
||||||
.size = 0,
|
|
||||||
.state = 0,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return loopback;
|
return loopback;
|
||||||
}
|
}
|
||||||
|
|
||||||
LoopbackInterface::~LoopbackInterface()
|
BAN::ErrorOr<void> LoopbackInterface::send_bytes(BAN::MACAddress destination, EtherType protocol, BAN::ConstByteSpan buffer)
|
||||||
{
|
{
|
||||||
m_thread_should_die = true;
|
ASSERT(buffer.size() + sizeof(EthernetHeader) <= buffer_size);
|
||||||
m_thread_blocker.unblock();
|
|
||||||
|
|
||||||
while (!m_thread_is_dead)
|
SpinLockGuard _(m_buffer_lock);
|
||||||
Processor::yield();
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::ErrorOr<void> LoopbackInterface::send_bytes(BAN::MACAddress destination, EtherType protocol, BAN::Span<const BAN::ConstByteSpan> payload)
|
uint8_t* buffer_vaddr = reinterpret_cast<uint8_t*>(m_buffer->vaddr());
|
||||||
{
|
|
||||||
auto& descriptor =
|
|
||||||
[&]() -> Descriptor&
|
|
||||||
{
|
|
||||||
LockGuard _(m_buffer_lock);
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
auto& descriptor = m_descriptors[m_buffer_head];
|
|
||||||
if (descriptor.state == 0)
|
|
||||||
{
|
|
||||||
m_buffer_head = (m_buffer_head + 1) % buffer_count;
|
|
||||||
descriptor.state = 1;
|
|
||||||
return descriptor;
|
|
||||||
}
|
|
||||||
m_thread_blocker.block_indefinite(&m_buffer_lock);
|
|
||||||
}
|
|
||||||
}();
|
|
||||||
|
|
||||||
auto& ethernet_header = *reinterpret_cast<EthernetHeader*>(descriptor.addr);
|
auto& ethernet_header = *reinterpret_cast<EthernetHeader*>(buffer_vaddr);
|
||||||
ethernet_header.dst_mac = destination;
|
ethernet_header.dst_mac = destination;
|
||||||
ethernet_header.src_mac = get_mac_address();
|
ethernet_header.src_mac = get_mac_address();
|
||||||
ethernet_header.ether_type = protocol;
|
ethernet_header.ether_type = protocol;
|
||||||
|
|
||||||
size_t packet_size = sizeof(EthernetHeader);
|
memcpy(buffer_vaddr + sizeof(EthernetHeader), buffer.data(), buffer.size());
|
||||||
for (const auto& buffer : payload)
|
|
||||||
{
|
|
||||||
ASSERT(packet_size + buffer.size() <= buffer_size);
|
|
||||||
memcpy(descriptor.addr + packet_size, buffer.data(), buffer.size());
|
|
||||||
packet_size += buffer.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
LockGuard _(m_buffer_lock);
|
NetworkManager::get().on_receive(*this, BAN::ConstByteSpan {
|
||||||
descriptor.size = packet_size;
|
buffer_vaddr,
|
||||||
descriptor.state = 2;
|
buffer.size() + sizeof(EthernetHeader)
|
||||||
m_thread_blocker.unblock();
|
});
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoopbackInterface::receive_thread()
|
|
||||||
{
|
|
||||||
LockGuard _(m_buffer_lock);
|
|
||||||
|
|
||||||
while (!m_thread_should_die)
|
|
||||||
{
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
auto& descriptor = m_descriptors[m_buffer_tail];
|
|
||||||
if (descriptor.state != 2)
|
|
||||||
break;
|
|
||||||
m_buffer_tail = (m_buffer_tail + 1) % buffer_count;
|
|
||||||
|
|
||||||
m_buffer_lock.unlock();
|
|
||||||
|
|
||||||
NetworkManager::get().on_receive(*this, {
|
|
||||||
descriptor.addr,
|
|
||||||
descriptor.size,
|
|
||||||
});
|
|
||||||
|
|
||||||
m_buffer_lock.lock();
|
|
||||||
|
|
||||||
descriptor.size = 0;
|
|
||||||
descriptor.state = 0;
|
|
||||||
m_thread_blocker.unblock();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_thread_blocker.block_indefinite(&m_buffer_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_thread_is_dead = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,28 +3,15 @@
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
{
|
{
|
||||||
|
|
||||||
uint16_t calculate_internet_checksum(BAN::ConstByteSpan buffer)
|
uint16_t calculate_internet_checksum(BAN::ConstByteSpan packet, const PseudoHeader& pseudo_header)
|
||||||
{
|
|
||||||
return calculate_internet_checksum({ &buffer, 1 });
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t calculate_internet_checksum(BAN::Span<const BAN::ConstByteSpan> buffers)
|
|
||||||
{
|
{
|
||||||
uint32_t checksum = 0;
|
uint32_t checksum = 0;
|
||||||
|
for (size_t i = 0; i < sizeof(pseudo_header) / sizeof(uint16_t); i++)
|
||||||
for (size_t i = 0; i < buffers.size(); i++)
|
checksum += BAN::host_to_network_endian(reinterpret_cast<const uint16_t*>(&pseudo_header)[i]);
|
||||||
{
|
for (size_t i = 0; i < packet.size() / sizeof(uint16_t); i++)
|
||||||
auto buffer = buffers[i];
|
checksum += BAN::host_to_network_endian(reinterpret_cast<const uint16_t*>(packet.data())[i]);
|
||||||
|
if (packet.size() % 2)
|
||||||
const uint16_t* buffer_u16 = reinterpret_cast<const uint16_t*>(buffer.data());
|
checksum += (uint16_t)packet[packet.size() - 1] << 8;
|
||||||
for (size_t j = 0; j < buffer.size() / 2; j++)
|
|
||||||
checksum += BAN::host_to_network_endian(buffer_u16[j]);
|
|
||||||
if (buffer.size() % 2 == 0)
|
|
||||||
continue;
|
|
||||||
ASSERT(i == buffers.size() - 1);
|
|
||||||
checksum += buffer[buffer.size() - 1] << 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (checksum >> 16)
|
while (checksum >> 16)
|
||||||
checksum = (checksum >> 16) + (checksum & 0xFFFF);
|
checksum = (checksum >> 16) + (checksum & 0xFFFF);
|
||||||
return ~(uint16_t)checksum;
|
return ~(uint16_t)checksum;
|
||||||
|
|
|
||||||
|
|
@ -154,18 +154,18 @@ namespace Kernel
|
||||||
return;
|
return;
|
||||||
auto ethernet_header = packet.as<const EthernetHeader>();
|
auto ethernet_header = packet.as<const EthernetHeader>();
|
||||||
|
|
||||||
auto packet_data = packet.slice(sizeof(EthernetHeader));
|
|
||||||
|
|
||||||
switch (ethernet_header.ether_type)
|
switch (ethernet_header.ether_type)
|
||||||
{
|
{
|
||||||
case EtherType::ARP:
|
case EtherType::ARP:
|
||||||
if (auto ret = m_ipv4_layer->arp_table().handle_arp_packet(interface, packet_data); ret.is_error())
|
{
|
||||||
dwarnln("ARP: {}", ret.error());
|
m_ipv4_layer->arp_table().add_arp_packet(interface, packet.slice(sizeof(EthernetHeader)));
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case EtherType::IPv4:
|
case EtherType::IPv4:
|
||||||
if (auto ret = m_ipv4_layer->handle_ipv4_packet(interface, packet_data); ret.is_error())
|
{
|
||||||
dwarnln("IPv4; {}", ret.error());
|
m_ipv4_layer->add_ipv4_packet(interface, packet.slice(sizeof(EthernetHeader)));
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
dprintln_if(DEBUG_ETHERTYPE, "Unknown EtherType 0x{4H}", (uint16_t)ethernet_header.ether_type);
|
dprintln_if(DEBUG_ETHERTYPE, "Unknown EtherType 0x{4H}", (uint16_t)ethernet_header.ether_type);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,6 @@
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
{
|
{
|
||||||
|
|
||||||
// each buffer is 7440 bytes + padding = 8192
|
|
||||||
constexpr size_t s_buffer_size = 8192;
|
|
||||||
|
|
||||||
bool RTL8169::probe(PCI::Device& pci_device)
|
bool RTL8169::probe(PCI::Device& pci_device)
|
||||||
{
|
{
|
||||||
if (pci_device.vendor_id() != 0x10ec)
|
if (pci_device.vendor_id() != 0x10ec)
|
||||||
|
|
@ -71,28 +68,9 @@ namespace Kernel
|
||||||
// lock config registers
|
// lock config registers
|
||||||
m_io_bar_region->write8(RTL8169_IO_9346CR, RTL8169_9346CR_MODE_NORMAL);
|
m_io_bar_region->write8(RTL8169_IO_9346CR, RTL8169_9346CR_MODE_NORMAL);
|
||||||
|
|
||||||
auto* thread = TRY(Thread::create_kernel([](void* rtl8169_ptr) {
|
|
||||||
static_cast<RTL8169*>(rtl8169_ptr)->receive_thread();
|
|
||||||
}, this));
|
|
||||||
if (auto ret = Processor::scheduler().add_thread(thread); ret.is_error())
|
|
||||||
{
|
|
||||||
delete thread;
|
|
||||||
return ret.release_error();
|
|
||||||
}
|
|
||||||
m_thread_is_dead = false;
|
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
RTL8169::~RTL8169()
|
|
||||||
{
|
|
||||||
m_thread_should_die = true;
|
|
||||||
m_thread_blocker.unblock();
|
|
||||||
|
|
||||||
while (!m_thread_is_dead)
|
|
||||||
Processor::yield();
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::ErrorOr<void> RTL8169::reset()
|
BAN::ErrorOr<void> RTL8169::reset()
|
||||||
{
|
{
|
||||||
m_io_bar_region->write8(RTL8169_IO_CR, RTL8169_CR_RST);
|
m_io_bar_region->write8(RTL8169_IO_CR, RTL8169_CR_RST);
|
||||||
|
|
@ -107,12 +85,15 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<void> RTL8169::initialize_rx()
|
BAN::ErrorOr<void> RTL8169::initialize_rx()
|
||||||
{
|
{
|
||||||
m_rx_buffer_region = TRY(DMARegion::create(m_rx_descriptor_count * s_buffer_size));
|
// each buffer is 7440 bytes + padding = 8192
|
||||||
|
constexpr size_t buffer_size = 2 * PAGE_SIZE;
|
||||||
|
|
||||||
|
m_rx_buffer_region = TRY(DMARegion::create(m_rx_descriptor_count * buffer_size));
|
||||||
m_rx_descriptor_region = TRY(DMARegion::create(m_rx_descriptor_count * sizeof(RTL8169Descriptor)));
|
m_rx_descriptor_region = TRY(DMARegion::create(m_rx_descriptor_count * sizeof(RTL8169Descriptor)));
|
||||||
|
|
||||||
for (size_t i = 0; i < m_rx_descriptor_count; i++)
|
for (size_t i = 0; i < m_rx_descriptor_count; i++)
|
||||||
{
|
{
|
||||||
const paddr_t rx_buffer_paddr = m_rx_buffer_region->paddr() + i * s_buffer_size;
|
const paddr_t rx_buffer_paddr = m_rx_buffer_region->paddr() + i * buffer_size;
|
||||||
|
|
||||||
uint32_t command = 0x1FF8 | RTL8169_DESC_CMD_OWN;
|
uint32_t command = 0x1FF8 | RTL8169_DESC_CMD_OWN;
|
||||||
if (i == m_rx_descriptor_count - 1)
|
if (i == m_rx_descriptor_count - 1)
|
||||||
|
|
@ -139,17 +120,21 @@ namespace Kernel
|
||||||
// configure max rx packet size
|
// configure max rx packet size
|
||||||
m_io_bar_region->write16(RTL8169_IO_RMS, RTL8169_RMS_MAX);
|
m_io_bar_region->write16(RTL8169_IO_RMS, RTL8169_RMS_MAX);
|
||||||
|
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<void> RTL8169::initialize_tx()
|
BAN::ErrorOr<void> RTL8169::initialize_tx()
|
||||||
{
|
{
|
||||||
m_tx_buffer_region = TRY(DMARegion::create(m_tx_descriptor_count * s_buffer_size));
|
// each buffer is 7440 bytes + padding = 8192
|
||||||
|
constexpr size_t buffer_size = 2 * PAGE_SIZE;
|
||||||
|
|
||||||
|
m_tx_buffer_region = TRY(DMARegion::create(m_tx_descriptor_count * buffer_size));
|
||||||
m_tx_descriptor_region = TRY(DMARegion::create(m_tx_descriptor_count * sizeof(RTL8169Descriptor)));
|
m_tx_descriptor_region = TRY(DMARegion::create(m_tx_descriptor_count * sizeof(RTL8169Descriptor)));
|
||||||
|
|
||||||
for (size_t i = 0; i < m_tx_descriptor_count; i++)
|
for (size_t i = 0; i < m_tx_descriptor_count; i++)
|
||||||
{
|
{
|
||||||
const paddr_t tx_buffer_paddr = m_tx_buffer_region->paddr() + i * s_buffer_size;
|
const paddr_t tx_buffer_paddr = m_tx_buffer_region->paddr() + i * buffer_size;
|
||||||
|
|
||||||
uint32_t command = 0;
|
uint32_t command = 0;
|
||||||
if (i == m_tx_descriptor_count - 1)
|
if (i == m_tx_descriptor_count - 1)
|
||||||
|
|
@ -209,8 +194,14 @@ namespace Kernel
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<void> RTL8169::send_bytes(BAN::MACAddress destination, EtherType protocol, BAN::Span<const BAN::ConstByteSpan> payload)
|
BAN::ErrorOr<void> RTL8169::send_bytes(BAN::MACAddress destination, EtherType protocol, BAN::ConstByteSpan buffer)
|
||||||
{
|
{
|
||||||
|
constexpr size_t buffer_size = 8192;
|
||||||
|
|
||||||
|
const uint16_t packet_size = sizeof(EthernetHeader) + buffer.size();
|
||||||
|
if (packet_size > buffer_size)
|
||||||
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
|
||||||
if (!link_up())
|
if (!link_up())
|
||||||
return BAN::Error::from_errno(EADDRNOTAVAIL);
|
return BAN::Error::from_errno(EADDRNOTAVAIL);
|
||||||
|
|
||||||
|
|
@ -228,20 +219,14 @@ namespace Kernel
|
||||||
|
|
||||||
m_lock.unlock(state);
|
m_lock.unlock(state);
|
||||||
|
|
||||||
auto* tx_buffer = reinterpret_cast<uint8_t*>(m_tx_buffer_region->vaddr() + tx_current * s_buffer_size);
|
auto* tx_buffer = reinterpret_cast<uint8_t*>(m_tx_buffer_region->vaddr() + tx_current * buffer_size);
|
||||||
|
|
||||||
// write packet
|
// write packet
|
||||||
auto& ethernet_header = *reinterpret_cast<EthernetHeader*>(tx_buffer);
|
auto& ethernet_header = *reinterpret_cast<EthernetHeader*>(tx_buffer);
|
||||||
ethernet_header.dst_mac = destination;
|
ethernet_header.dst_mac = destination;
|
||||||
ethernet_header.src_mac = get_mac_address();
|
ethernet_header.src_mac = get_mac_address();
|
||||||
ethernet_header.ether_type = protocol;
|
ethernet_header.ether_type = protocol;
|
||||||
|
memcpy(tx_buffer + sizeof(EthernetHeader), buffer.data(), buffer.size());
|
||||||
size_t packet_size = sizeof(EthernetHeader);
|
|
||||||
for (const auto& buffer : payload)
|
|
||||||
{
|
|
||||||
memcpy(tx_buffer + packet_size, buffer.data(), buffer.size());
|
|
||||||
packet_size += buffer.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
// give packet ownership to NIC
|
// give packet ownership to NIC
|
||||||
uint32_t command = packet_size | RTL8169_DESC_CMD_OWN | RTL8169_DESC_CMD_LS | RTL8169_DESC_CMD_FS;
|
uint32_t command = packet_size | RTL8169_DESC_CMD_OWN | RTL8169_DESC_CMD_LS | RTL8169_DESC_CMD_FS;
|
||||||
|
|
@ -255,50 +240,6 @@ namespace Kernel
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void RTL8169::receive_thread()
|
|
||||||
{
|
|
||||||
SpinLockGuard _(m_lock);
|
|
||||||
|
|
||||||
while (!m_thread_should_die)
|
|
||||||
{
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
auto& descriptor = reinterpret_cast<volatile RTL8169Descriptor*>(m_rx_descriptor_region->vaddr())[m_rx_current];
|
|
||||||
if (descriptor.command & RTL8169_DESC_CMD_OWN)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// packet buffer can only hold single packet, so we should not receive any multi-descriptor packets
|
|
||||||
ASSERT((descriptor.command & RTL8169_DESC_CMD_LS) && (descriptor.command & RTL8169_DESC_CMD_FS));
|
|
||||||
|
|
||||||
const uint16_t packet_length = descriptor.command & 0x3FFF;
|
|
||||||
if (packet_length > s_buffer_size)
|
|
||||||
dwarnln("Got {} bytes to {} byte buffer", packet_length, s_buffer_size);
|
|
||||||
else if (descriptor.command & (1u << 21))
|
|
||||||
; // descriptor has an error
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_lock.unlock(InterruptState::Enabled);
|
|
||||||
|
|
||||||
NetworkManager::get().on_receive(*this, BAN::ConstByteSpan {
|
|
||||||
reinterpret_cast<const uint8_t*>(m_rx_buffer_region->vaddr() + m_rx_current * s_buffer_size),
|
|
||||||
packet_length
|
|
||||||
});
|
|
||||||
|
|
||||||
m_lock.lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_rx_current = (m_rx_current + 1) % m_rx_descriptor_count;
|
|
||||||
|
|
||||||
descriptor.command = descriptor.command | RTL8169_DESC_CMD_OWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
SpinLockAsMutex smutex(m_lock, InterruptState::Enabled);
|
|
||||||
m_thread_blocker.block_indefinite(&smutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_thread_is_dead = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RTL8169::handle_irq()
|
void RTL8169::handle_irq()
|
||||||
{
|
{
|
||||||
const uint16_t interrupt_status = m_io_bar_region->read16(RTL8169_IO_ISR);
|
const uint16_t interrupt_status = m_io_bar_region->read16(RTL8169_IO_ISR);
|
||||||
|
|
@ -310,7 +251,7 @@ namespace Kernel
|
||||||
dprintln("link status -> {}", m_link_up.load());
|
dprintln("link status -> {}", m_link_up.load());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (interrupt_status & (RTL8169_IR_TOK | RTL8169_IR_ROK))
|
if (interrupt_status & RTL8169_IR_TOK)
|
||||||
{
|
{
|
||||||
SpinLockGuard _(m_lock);
|
SpinLockGuard _(m_lock);
|
||||||
m_thread_blocker.unblock();
|
m_thread_blocker.unblock();
|
||||||
|
|
@ -325,6 +266,38 @@ namespace Kernel
|
||||||
if (interrupt_status & RTL8169_IR_FVOW)
|
if (interrupt_status & RTL8169_IR_FVOW)
|
||||||
dwarnln("Rx FIFO overflow");
|
dwarnln("Rx FIFO overflow");
|
||||||
// dont log TDU is sent after each sent packet
|
// dont log TDU is sent after each sent packet
|
||||||
|
|
||||||
|
if (!(interrupt_status & RTL8169_IR_ROK))
|
||||||
|
return;
|
||||||
|
|
||||||
|
constexpr size_t buffer_size = 8192;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
auto& descriptor = reinterpret_cast<volatile RTL8169Descriptor*>(m_rx_descriptor_region->vaddr())[m_rx_current];
|
||||||
|
if (descriptor.command & RTL8169_DESC_CMD_OWN)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// packet buffer can only hold single packet, so we should not receive any multi-descriptor packets
|
||||||
|
ASSERT((descriptor.command & RTL8169_DESC_CMD_LS) && (descriptor.command & RTL8169_DESC_CMD_FS));
|
||||||
|
|
||||||
|
const uint16_t packet_length = descriptor.command & 0x3FFF;
|
||||||
|
if (packet_length > buffer_size)
|
||||||
|
dwarnln("Got {} bytes to {} byte buffer", packet_length, buffer_size);
|
||||||
|
else if (descriptor.command & (1u << 21))
|
||||||
|
; // descriptor has an error
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NetworkManager::get().on_receive(*this, BAN::ConstByteSpan {
|
||||||
|
reinterpret_cast<const uint8_t*>(m_rx_buffer_region->vaddr() + m_rx_current * buffer_size),
|
||||||
|
packet_length
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
m_rx_current = (m_rx_current + 1) % m_rx_descriptor_count;
|
||||||
|
|
||||||
|
descriptor.command = descriptor.command | RTL8169_DESC_CMD_OWN;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netinet/tcp.h>
|
|
||||||
#include <sys/epoll.h>
|
#include <sys/epoll.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
|
|
@ -25,19 +24,26 @@ namespace Kernel
|
||||||
static constexpr size_t s_recv_window_buffer_size = 16 * PAGE_SIZE;
|
static constexpr size_t s_recv_window_buffer_size = 16 * PAGE_SIZE;
|
||||||
static constexpr size_t s_send_window_buffer_size = 16 * PAGE_SIZE;
|
static constexpr size_t s_send_window_buffer_size = 16 * PAGE_SIZE;
|
||||||
|
|
||||||
// allows upto 1 MiB windows
|
|
||||||
static constexpr uint8_t s_window_shift = 4;
|
|
||||||
|
|
||||||
// https://www.rfc-editor.org/rfc/rfc1122 4.2.2.6
|
|
||||||
static constexpr uint16_t s_default_mss = 536;
|
|
||||||
|
|
||||||
BAN::ErrorOr<BAN::RefPtr<TCPSocket>> TCPSocket::create(NetworkLayer& network_layer, const Info& info)
|
BAN::ErrorOr<BAN::RefPtr<TCPSocket>> TCPSocket::create(NetworkLayer& network_layer, const Info& info)
|
||||||
{
|
{
|
||||||
auto socket = TRY(BAN::RefPtr<TCPSocket>::create(network_layer, info));
|
auto socket = TRY(BAN::RefPtr<TCPSocket>::create(network_layer, info));
|
||||||
socket->m_last_sent_window_size = s_recv_window_buffer_size;
|
socket->m_recv_window.buffer = TRY(VirtualRange::create_to_vaddr_range(
|
||||||
socket->m_recv_window.buffer = TRY(ByteRingBuffer::create(s_recv_window_buffer_size));
|
PageTable::kernel(),
|
||||||
socket->m_recv_window.scale_shift = s_window_shift;
|
KERNEL_OFFSET,
|
||||||
socket->m_send_window.buffer = TRY(ByteRingBuffer::create(s_send_window_buffer_size));
|
~(vaddr_t)0,
|
||||||
|
s_recv_window_buffer_size,
|
||||||
|
PageTable::Flags::ReadWrite | PageTable::Flags::Present,
|
||||||
|
true, false
|
||||||
|
));
|
||||||
|
socket->m_recv_window.scale_shift = PAGE_SIZE_SHIFT; // use PAGE_SIZE windows
|
||||||
|
socket->m_send_window.buffer = TRY(VirtualRange::create_to_vaddr_range(
|
||||||
|
PageTable::kernel(),
|
||||||
|
KERNEL_OFFSET,
|
||||||
|
~(vaddr_t)0,
|
||||||
|
s_send_window_buffer_size,
|
||||||
|
PageTable::Flags::ReadWrite | PageTable::Flags::Present,
|
||||||
|
true, false
|
||||||
|
));
|
||||||
socket->m_thread = TRY(Thread::create_kernel(
|
socket->m_thread = TRY(Thread::create_kernel(
|
||||||
[](void* socket_ptr)
|
[](void* socket_ptr)
|
||||||
{
|
{
|
||||||
|
|
@ -94,13 +100,12 @@ namespace Kernel
|
||||||
return_inode->m_listen_parent = this;
|
return_inode->m_listen_parent = this;
|
||||||
return_inode->m_connection_info.emplace(connection.target);
|
return_inode->m_connection_info.emplace(connection.target);
|
||||||
return_inode->m_recv_window.start_seq = connection.target_start_seq;
|
return_inode->m_recv_window.start_seq = connection.target_start_seq;
|
||||||
return_inode->m_send_window.scale_shift = connection.window_scale;
|
|
||||||
return_inode->m_send_window.mss = connection.maximum_seqment_size;
|
|
||||||
return_inode->m_next_flags = SYN | ACK;
|
return_inode->m_next_flags = SYN | ACK;
|
||||||
return_inode->m_next_state = State::SynReceived;
|
return_inode->m_next_state = State::SynReceived;
|
||||||
|
return_inode->m_mutex.unlock();
|
||||||
|
|
||||||
if (!return_inode->m_connection_info->has_window_scale)
|
if (!return_inode->m_connection_info->has_window_scale)
|
||||||
return_inode->m_recv_window.scale_shift = 0;
|
return_inode->m_recv_window.scale_shift = 0;
|
||||||
return_inode->m_mutex.unlock();
|
|
||||||
|
|
||||||
TRY(m_listen_children.emplace(listen_key, return_inode));
|
TRY(m_listen_children.emplace(listen_key, return_inode));
|
||||||
|
|
||||||
|
|
@ -192,7 +197,8 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<size_t> TCPSocket::recvmsg_impl(msghdr& message, int flags)
|
BAN::ErrorOr<size_t> TCPSocket::recvmsg_impl(msghdr& message, int flags)
|
||||||
{
|
{
|
||||||
if (flags & ~(MSG_PEEK))
|
flags &= (MSG_OOB | MSG_PEEK | MSG_WAITALL);
|
||||||
|
if (flags != 0)
|
||||||
{
|
{
|
||||||
dwarnln("TODO: recvmsg with flags 0x{H}", flags);
|
dwarnln("TODO: recvmsg with flags 0x{H}", flags);
|
||||||
return BAN::Error::from_errno(ENOTSUP);
|
return BAN::Error::from_errno(ENOTSUP);
|
||||||
|
|
@ -200,14 +206,14 @@ namespace Kernel
|
||||||
|
|
||||||
if (CMSG_FIRSTHDR(&message))
|
if (CMSG_FIRSTHDR(&message))
|
||||||
{
|
{
|
||||||
dprintln_if(DEBUG_TCP, "ignoring recvmsg control message");
|
dwarnln("ignoring recvmsg control message");
|
||||||
message.msg_controllen = 0;
|
message.msg_controllen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_has_connected)
|
if (!m_has_connected)
|
||||||
return BAN::Error::from_errno(ENOTCONN);
|
return BAN::Error::from_errno(ENOTCONN);
|
||||||
|
|
||||||
while (m_recv_window.buffer->empty())
|
while (m_recv_window.data_size == 0)
|
||||||
{
|
{
|
||||||
if (m_state != State::Established)
|
if (m_state != State::Established)
|
||||||
return return_with_maybe_zero();
|
return return_with_maybe_zero();
|
||||||
|
|
@ -217,34 +223,21 @@ namespace Kernel
|
||||||
message.msg_flags = 0;
|
message.msg_flags = 0;
|
||||||
|
|
||||||
size_t total_recv = 0;
|
size_t total_recv = 0;
|
||||||
for (int i = 0; i < message.msg_iovlen && total_recv < m_recv_window.buffer->size(); i++)
|
for (int i = 0; i < message.msg_iovlen; i++)
|
||||||
{
|
{
|
||||||
auto& iov = message.msg_iov[i];
|
auto* recv_buffer = reinterpret_cast<uint8_t*>(m_recv_window.buffer->vaddr());
|
||||||
|
|
||||||
const size_t nrecv = BAN::Math::min(iov.iov_len, m_recv_window.buffer->size() - total_recv);
|
const size_t nrecv = BAN::Math::min<size_t>(message.msg_iov[i].iov_len, m_recv_window.data_size);
|
||||||
memcpy(iov.iov_base, m_recv_window.buffer->get_data().data() + total_recv, nrecv);
|
memcpy(message.msg_iov[i].iov_base, recv_buffer, nrecv);
|
||||||
|
|
||||||
total_recv += nrecv;
|
total_recv += nrecv;
|
||||||
}
|
m_recv_window.data_size -= nrecv;
|
||||||
|
m_recv_window.start_seq += nrecv;
|
||||||
|
if (m_recv_window.data_size == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
if (!(flags & MSG_PEEK))
|
// TODO: use circular buffer to avoid this
|
||||||
{
|
memmove(recv_buffer, recv_buffer + nrecv, m_recv_window.data_size);
|
||||||
m_recv_window.buffer->pop(total_recv);
|
|
||||||
m_recv_window.start_seq += total_recv;
|
|
||||||
}
|
|
||||||
|
|
||||||
const size_t update_window_threshold = m_recv_window.buffer->capacity() / 8;
|
|
||||||
const bool should_update_window_size =
|
|
||||||
m_last_sent_window_size != m_recv_window.buffer->capacity() && (
|
|
||||||
(m_last_sent_window_size == 0) ||
|
|
||||||
(m_recv_window.buffer->empty()) ||
|
|
||||||
(m_last_sent_window_size + update_window_threshold <= m_recv_window.buffer->free())
|
|
||||||
);
|
|
||||||
|
|
||||||
if (should_update_window_size || m_should_send_zero_window)
|
|
||||||
{
|
|
||||||
m_should_send_window_update = true;
|
|
||||||
m_thread_blocker.unblock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return total_recv;
|
return total_recv;
|
||||||
|
|
@ -264,7 +257,7 @@ namespace Kernel
|
||||||
if (!m_has_connected)
|
if (!m_has_connected)
|
||||||
return BAN::Error::from_errno(ENOTCONN);
|
return BAN::Error::from_errno(ENOTCONN);
|
||||||
|
|
||||||
while (m_send_window.buffer->full())
|
while (m_send_window.data_size == m_send_window.buffer->size())
|
||||||
{
|
{
|
||||||
if (m_state != State::Established)
|
if (m_state != State::Established)
|
||||||
return return_with_maybe_zero();
|
return return_with_maybe_zero();
|
||||||
|
|
@ -274,14 +267,17 @@ namespace Kernel
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t total_sent = 0;
|
size_t total_sent = 0;
|
||||||
for (int i = 0; i < message.msg_iovlen && !m_send_window.buffer->full(); i++)
|
for (int i = 0; i < message.msg_iovlen; i++)
|
||||||
{
|
{
|
||||||
const auto& iov = message.msg_iov[i];
|
auto* send_buffer = reinterpret_cast<uint8_t*>(m_send_window.buffer->vaddr());
|
||||||
|
|
||||||
const size_t nsend = BAN::Math::min(iov.iov_len, m_send_window.buffer->free());
|
const size_t nsend = BAN::Math::min<size_t>(message.msg_iov[i].iov_len, m_send_window.buffer->size() - m_send_window.data_size);
|
||||||
m_send_window.buffer->push({ static_cast<const uint8_t*>(iov.iov_base), nsend });
|
memcpy(send_buffer + m_send_window.data_size, message.msg_iov[i].iov_base, nsend);
|
||||||
|
|
||||||
total_sent += nsend;
|
total_sent += nsend;
|
||||||
|
m_send_window.data_size += nsend;
|
||||||
|
if (m_send_window.data_size == m_send_window.buffer->size())
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_thread_blocker.unblock();
|
m_thread_blocker.unblock();
|
||||||
|
|
@ -302,16 +298,12 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<void> TCPSocket::getsockopt_impl(int level, int option, void* value, socklen_t* value_len)
|
BAN::ErrorOr<void> TCPSocket::getsockopt_impl(int level, int option, void* value, socklen_t* value_len)
|
||||||
{
|
{
|
||||||
int result;
|
if (level != SOL_SOCKET)
|
||||||
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
|
||||||
switch (level)
|
int result;
|
||||||
{
|
|
||||||
case SOL_SOCKET:
|
|
||||||
switch (option)
|
switch (option)
|
||||||
{
|
{
|
||||||
case SO_KEEPALIVE:
|
|
||||||
result = m_keep_alive;
|
|
||||||
break;
|
|
||||||
case SO_ERROR:
|
case SO_ERROR:
|
||||||
result = 0;
|
result = 0;
|
||||||
break;
|
break;
|
||||||
|
|
@ -319,27 +311,10 @@ namespace Kernel
|
||||||
result = m_send_window.scaled_size();
|
result = m_send_window.scaled_size();
|
||||||
break;
|
break;
|
||||||
case SO_RCVBUF:
|
case SO_RCVBUF:
|
||||||
result = m_recv_window.buffer->capacity();
|
result = m_recv_window.buffer->size();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dwarnln("getsockopt(SOL_SOCKET, {})", option);
|
return BAN::Error::from_errno(ENOTSUP);
|
||||||
return BAN::Error::from_errno(ENOPROTOOPT);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case IPPROTO_TCP:
|
|
||||||
switch (option)
|
|
||||||
{
|
|
||||||
case TCP_NODELAY:
|
|
||||||
result = m_no_delay;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
dwarnln("getsockopt(IPPROTO_TCP, {})", option);
|
|
||||||
return BAN::Error::from_errno(ENOPROTOOPT);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
dwarnln("getsockopt({}, {})", level, option);
|
|
||||||
return BAN::Error::from_errno(EINVAL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t len = BAN::Math::min<size_t>(sizeof(result), *value_len);
|
const size_t len = BAN::Math::min<size_t>(sizeof(result), *value_len);
|
||||||
|
|
@ -349,50 +324,12 @@ namespace Kernel
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<void> TCPSocket::setsockopt_impl(int level, int option, const void* value, socklen_t value_len)
|
|
||||||
{
|
|
||||||
switch (level)
|
|
||||||
{
|
|
||||||
case SOL_SOCKET:
|
|
||||||
switch (option)
|
|
||||||
{
|
|
||||||
case SO_KEEPALIVE:
|
|
||||||
if (value_len != sizeof(int))
|
|
||||||
return BAN::Error::from_errno(EINVAL);
|
|
||||||
m_keep_alive = *static_cast<const int*>(value);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
dwarnln("setsockopt(SOL_SOCKET, {})", option);
|
|
||||||
return BAN::Error::from_errno(ENOPROTOOPT);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case IPPROTO_TCP:
|
|
||||||
switch (option)
|
|
||||||
{
|
|
||||||
case TCP_NODELAY:
|
|
||||||
if (value_len != sizeof(int))
|
|
||||||
return BAN::Error::from_errno(EINVAL);
|
|
||||||
m_no_delay = *static_cast<const int*>(value);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
dwarnln("setsockopt(IPPROTO_TCP, {})", option);
|
|
||||||
return BAN::Error::from_errno(ENOPROTOOPT);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
dwarnln("setsockopt({}, {})", level, option);
|
|
||||||
return BAN::Error::from_errno(EINVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::ErrorOr<long> TCPSocket::ioctl_impl(int request, void* argument)
|
BAN::ErrorOr<long> TCPSocket::ioctl_impl(int request, void* argument)
|
||||||
{
|
{
|
||||||
switch (request)
|
switch (request)
|
||||||
{
|
{
|
||||||
case FIONREAD:
|
case FIONREAD:
|
||||||
*static_cast<int*>(argument) = m_recv_window.buffer->size();
|
*static_cast<int*>(argument) = m_recv_window.data_size;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -405,14 +342,14 @@ namespace Kernel
|
||||||
return true;
|
return true;
|
||||||
if (m_state == State::Listen)
|
if (m_state == State::Listen)
|
||||||
return !m_pending_connections.empty();
|
return !m_pending_connections.empty();
|
||||||
return !m_recv_window.buffer->empty();
|
return m_recv_window.data_size > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TCPSocket::can_write_impl() const
|
bool TCPSocket::can_write_impl() const
|
||||||
{
|
{
|
||||||
if (m_state != State::Established)
|
if (m_state != State::Established)
|
||||||
return false;
|
return false;
|
||||||
return !m_send_window.buffer->full();
|
return m_send_window.data_size < m_send_window.buffer->size();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TCPSocket::has_hungup_impl() const
|
bool TCPSocket::has_hungup_impl() const
|
||||||
|
|
@ -485,7 +422,7 @@ namespace Kernel
|
||||||
if (header.options[i] == TCPOption::NOP)
|
if (header.options[i] == TCPOption::NOP)
|
||||||
continue;
|
continue;
|
||||||
if (header.options[i] == TCPOption::MaximumSeqmentSize)
|
if (header.options[i] == TCPOption::MaximumSeqmentSize)
|
||||||
result.maximum_seqment_size = BAN::network_endian_to_host(*reinterpret_cast<const uint16_t*>(&header.options[i + 2]));
|
result.maximum_seqment_size = BAN::host_to_network_endian(*reinterpret_cast<const uint16_t*>(&header.options[i + 2]));
|
||||||
if (header.options[i] == TCPOption::WindowScale)
|
if (header.options[i] == TCPOption::WindowScale)
|
||||||
result.window_scale = header.options[i + 2];
|
result.window_scale = header.options[i + 2];
|
||||||
if (header.options[i + 1] == 0)
|
if (header.options[i + 1] == 0)
|
||||||
|
|
@ -496,28 +433,22 @@ namespace Kernel
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TCPSocket::get_protocol_header(BAN::ByteSpan header_buffer, BAN::ConstByteSpan payload, uint16_t dst_port, PseudoHeader pseudo_header)
|
void TCPSocket::add_protocol_header(BAN::ByteSpan packet, uint16_t dst_port, PseudoHeader pseudo_header)
|
||||||
{
|
{
|
||||||
ASSERT(m_next_flags);
|
ASSERT(m_next_flags);
|
||||||
ASSERT(m_mutex.locker() == Thread::current().tid());
|
ASSERT(m_mutex.locker() == Thread::current().tid());
|
||||||
ASSERT(header_buffer.size() == protocol_header_size());
|
|
||||||
|
|
||||||
m_last_sent_window_size = m_should_send_zero_window ? 0 : m_recv_window.buffer->free();
|
auto& header = packet.as<TCPHeader>();
|
||||||
|
memset(&header, 0, sizeof(TCPHeader));
|
||||||
auto& header = header_buffer.as<TCPHeader>();
|
memset(header.options, TCPOption::End, m_tcp_options_bytes);
|
||||||
header = {
|
|
||||||
.src_port = bound_port(),
|
|
||||||
.dst_port = dst_port,
|
|
||||||
.seq_number = m_send_window.current_seq + m_send_window.has_ghost_byte,
|
|
||||||
.ack_number = m_recv_window.start_seq + m_recv_window.buffer->size() + m_recv_window.has_ghost_byte,
|
|
||||||
.data_offset = (sizeof(TCPHeader) + m_tcp_options_bytes) / sizeof(uint32_t),
|
|
||||||
.flags = m_next_flags,
|
|
||||||
.window_size = BAN::Math::min<size_t>(0xFFFF, m_last_sent_window_size >> m_recv_window.scale_shift),
|
|
||||||
.checksum = 0,
|
|
||||||
.urgent_pointer = 0,
|
|
||||||
};
|
|
||||||
memset(header.options, 0, m_tcp_options_bytes);
|
|
||||||
|
|
||||||
|
header.src_port = bound_port();
|
||||||
|
header.dst_port = dst_port;
|
||||||
|
header.seq_number = m_send_window.current_seq + m_send_window.has_ghost_byte;
|
||||||
|
header.ack_number = m_recv_window.start_seq + m_recv_window.data_size + m_recv_window.has_ghost_byte;
|
||||||
|
header.data_offset = (sizeof(TCPHeader) + m_tcp_options_bytes) / sizeof(uint32_t);
|
||||||
|
header.window_size = BAN::Math::min<size_t>(0xFFFF, m_recv_window.buffer->size() >> m_recv_window.scale_shift);
|
||||||
|
header.flags = m_next_flags;
|
||||||
if (header.flags & FIN)
|
if (header.flags & FIN)
|
||||||
m_send_window.has_ghost_byte = true;
|
m_send_window.has_ghost_byte = true;
|
||||||
m_next_flags = 0;
|
m_next_flags = 0;
|
||||||
|
|
@ -536,39 +467,24 @@ namespace Kernel
|
||||||
|
|
||||||
if (m_connection_info->has_window_scale)
|
if (m_connection_info->has_window_scale)
|
||||||
add_tcp_header_option<4, TCPOption::WindowScale>(header, m_recv_window.scale_shift);
|
add_tcp_header_option<4, TCPOption::WindowScale>(header, m_recv_window.scale_shift);
|
||||||
header.window_size = BAN::Math::min<size_t>(0xFFFF, m_recv_window.buffer->capacity());
|
header.window_size = BAN::Math::min<size_t>(0xFFFF, m_recv_window.buffer->size());
|
||||||
|
|
||||||
|
m_send_window.mss = 1440;
|
||||||
m_send_window.start_seq++;
|
m_send_window.start_seq++;
|
||||||
m_send_window.current_seq = m_send_window.start_seq;
|
m_send_window.current_seq = m_send_window.start_seq;
|
||||||
}
|
}
|
||||||
|
|
||||||
const BAN::ConstByteSpan buffers[] {
|
pseudo_header.extra = packet.size();
|
||||||
BAN::ConstByteSpan::from(pseudo_header),
|
header.checksum = calculate_internet_checksum(packet, pseudo_header);
|
||||||
header_buffer,
|
|
||||||
payload,
|
|
||||||
};
|
|
||||||
header.checksum = calculate_internet_checksum({ buffers, sizeof(buffers) / sizeof(*buffers) });
|
|
||||||
|
|
||||||
dprintln_if(DEBUG_TCP, "sending {} {8b}", (uint8_t)m_state, header.flags);
|
dprintln_if(DEBUG_TCP, "sending {} {8b}", (uint8_t)m_state, header.flags);
|
||||||
dprintln_if(DEBUG_TCP, " ack {}", (uint32_t)header.ack_number);
|
dprintln_if(DEBUG_TCP, " {}", (uint32_t)header.ack_number);
|
||||||
dprintln_if(DEBUG_TCP, " seq {}", (uint32_t)header.seq_number);
|
dprintln_if(DEBUG_TCP, " {}", (uint32_t)header.seq_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TCPSocket::receive_packet(BAN::ConstByteSpan buffer, const sockaddr* sender, socklen_t sender_len)
|
void TCPSocket::receive_packet(BAN::ConstByteSpan buffer, const sockaddr* sender, socklen_t sender_len)
|
||||||
{
|
{
|
||||||
if (m_state == State::Listen)
|
(void)sender_len;
|
||||||
{
|
|
||||||
auto socket =
|
|
||||||
[&]() -> BAN::RefPtr<TCPSocket> {
|
|
||||||
LockGuard _(m_mutex);
|
|
||||||
if (auto it = m_listen_children.find(ListenKey(sender, sender_len)); it != m_listen_children.end())
|
|
||||||
return it->value;
|
|
||||||
return {};
|
|
||||||
}();
|
|
||||||
|
|
||||||
if (socket)
|
|
||||||
return socket->receive_packet(buffer, sender, sender_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
uint16_t checksum = 0;
|
uint16_t checksum = 0;
|
||||||
|
|
@ -581,17 +497,14 @@ namespace Kernel
|
||||||
auto interface = interface_or_error.release_value();
|
auto interface = interface_or_error.release_value();
|
||||||
|
|
||||||
auto& addr_in = *reinterpret_cast<const sockaddr_in*>(sender);
|
auto& addr_in = *reinterpret_cast<const sockaddr_in*>(sender);
|
||||||
const PseudoHeader pseudo_header {
|
checksum = calculate_internet_checksum(buffer,
|
||||||
|
PseudoHeader {
|
||||||
.src_ipv4 = BAN::IPv4Address(addr_in.sin_addr.s_addr),
|
.src_ipv4 = BAN::IPv4Address(addr_in.sin_addr.s_addr),
|
||||||
.dst_ipv4 = interface->get_ipv4_address(),
|
.dst_ipv4 = interface->get_ipv4_address(),
|
||||||
.protocol = NetworkProtocol::TCP,
|
.protocol = NetworkProtocol::TCP,
|
||||||
.length = buffer.size(),
|
.extra = buffer.size()
|
||||||
};
|
}
|
||||||
const BAN::ConstByteSpan buffers[] {
|
);
|
||||||
BAN::ConstByteSpan::from(pseudo_header),
|
|
||||||
buffer
|
|
||||||
};
|
|
||||||
checksum = calculate_internet_checksum({ buffers, sizeof(buffers) / sizeof(*buffers) });
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -611,14 +524,11 @@ namespace Kernel
|
||||||
const bool hungup_before = has_hungup_impl();
|
const bool hungup_before = has_hungup_impl();
|
||||||
|
|
||||||
auto& header = buffer.as<const TCPHeader>();
|
auto& header = buffer.as<const TCPHeader>();
|
||||||
|
|
||||||
dprintln_if(DEBUG_TCP, "receiving {} {8b}", (uint8_t)m_state, header.flags);
|
dprintln_if(DEBUG_TCP, "receiving {} {8b}", (uint8_t)m_state, header.flags);
|
||||||
dprintln_if(DEBUG_TCP, " ack {}", (uint32_t)header.ack_number);
|
dprintln_if(DEBUG_TCP, " {}", (uint32_t)header.ack_number);
|
||||||
dprintln_if(DEBUG_TCP, " seq {}", (uint32_t)header.seq_number);
|
dprintln_if(DEBUG_TCP, " {}", (uint32_t)header.seq_number);
|
||||||
|
|
||||||
m_send_window.non_scaled_size = header.window_size;
|
m_send_window.non_scaled_size = header.window_size;
|
||||||
if (m_send_window.scaled_size() == 0)
|
|
||||||
m_send_window.had_zero_window = true;
|
|
||||||
|
|
||||||
bool check_payload = false;
|
bool check_payload = false;
|
||||||
switch (m_state)
|
switch (m_state)
|
||||||
|
|
@ -637,7 +547,8 @@ namespace Kernel
|
||||||
}
|
}
|
||||||
|
|
||||||
auto options = parse_tcp_options(header);
|
auto options = parse_tcp_options(header);
|
||||||
m_send_window.mss = options.maximum_seqment_size.value_or(s_default_mss);
|
if (options.maximum_seqment_size.has_value())
|
||||||
|
m_send_window.mss = *options.maximum_seqment_size;
|
||||||
if (options.window_scale.has_value())
|
if (options.window_scale.has_value())
|
||||||
m_send_window.scale_shift = *options.window_scale;
|
m_send_window.scale_shift = *options.window_scale;
|
||||||
else
|
else
|
||||||
|
|
@ -662,34 +573,44 @@ namespace Kernel
|
||||||
m_has_connected = true;
|
m_has_connected = true;
|
||||||
break;
|
break;
|
||||||
case State::Listen:
|
case State::Listen:
|
||||||
if (header.flags != SYN)
|
if (header.flags == SYN)
|
||||||
dprintln_if(DEBUG_TCP, "Unexpected packet to listening socket");
|
{
|
||||||
else if (m_pending_connections.size() == m_pending_connections.capacity())
|
if (m_pending_connections.size() == m_pending_connections.capacity())
|
||||||
dprintln_if(DEBUG_TCP, "No storage to store pending connection");
|
dprintln_if(DEBUG_TCP, "No storage to store pending connection");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const auto options = parse_tcp_options(header);
|
|
||||||
|
|
||||||
ConnectionInfo connection_info;
|
ConnectionInfo connection_info;
|
||||||
memcpy(&connection_info.address, sender, sender_len);
|
memcpy(&connection_info.address, sender, sender_len);
|
||||||
connection_info.address_len = sender_len;
|
connection_info.address_len = sender_len;
|
||||||
connection_info.has_window_scale = options.window_scale.has_value();
|
connection_info.has_window_scale = parse_tcp_options(header).window_scale.has_value();
|
||||||
MUST(m_pending_connections.emplace(
|
MUST(m_pending_connections.emplace(
|
||||||
connection_info,
|
connection_info,
|
||||||
header.seq_number + 1,
|
header.seq_number + 1
|
||||||
options.maximum_seqment_size.value_or(s_default_mss),
|
|
||||||
options.window_scale.value_or(0)
|
|
||||||
));
|
));
|
||||||
|
|
||||||
epoll_notify(EPOLLIN);
|
epoll_notify(EPOLLIN);
|
||||||
m_thread_blocker.unblock();
|
m_thread_blocker.unblock();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto it = m_listen_children.find(ListenKey(sender, sender_len));
|
||||||
|
if (it == m_listen_children.end())
|
||||||
|
{
|
||||||
|
dprintln_if(DEBUG_TCP, "Unexpected packet to listening socket");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
auto socket = it->value;
|
||||||
|
m_mutex.unlock();
|
||||||
|
socket->receive_packet(buffer, sender, sender_len);
|
||||||
|
m_mutex.lock();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
case State::Established:
|
case State::Established:
|
||||||
check_payload = true;
|
check_payload = true;
|
||||||
if (!(header.flags & FIN))
|
if (!(header.flags & FIN))
|
||||||
break;
|
break;
|
||||||
if (m_recv_window.start_seq + m_recv_window.buffer->size() != header.seq_number)
|
if (m_recv_window.start_seq + m_recv_window.data_size != header.seq_number)
|
||||||
break;
|
break;
|
||||||
m_next_flags = FIN | ACK;
|
m_next_flags = FIN | ACK;
|
||||||
m_next_state = State::LastAck;
|
m_next_state = State::LastAck;
|
||||||
|
|
@ -738,9 +659,7 @@ namespace Kernel
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t expected_seq = m_recv_window.start_seq + m_recv_window.buffer->size() + m_recv_window.has_ghost_byte;
|
if (header.seq_number != m_recv_window.start_seq + m_recv_window.data_size + m_recv_window.has_ghost_byte)
|
||||||
|
|
||||||
if (header.seq_number > expected_seq)
|
|
||||||
dprintln_if(DEBUG_TCP, "Missing packets");
|
dprintln_if(DEBUG_TCP, "Missing packets");
|
||||||
else if (check_payload)
|
else if (check_payload)
|
||||||
{
|
{
|
||||||
|
|
@ -751,37 +670,28 @@ namespace Kernel
|
||||||
m_send_window.current_ack = header.ack_number;
|
m_send_window.current_ack = header.ack_number;
|
||||||
|
|
||||||
auto payload = buffer.slice(header.data_offset * sizeof(uint32_t));
|
auto payload = buffer.slice(header.data_offset * sizeof(uint32_t));
|
||||||
|
if (payload.size() > 0)
|
||||||
if (header.seq_number < expected_seq)
|
|
||||||
{
|
{
|
||||||
const uint32_t already_received_bytes = expected_seq - header.seq_number;
|
if (m_recv_window.data_size + payload.size() > m_recv_window.buffer->size())
|
||||||
if (already_received_bytes <= payload.size())
|
dprintln_if(DEBUG_TCP, "Cannot fit received bytes to window, waiting for retransmission");
|
||||||
payload = payload.slice(already_received_bytes);
|
|
||||||
else
|
else
|
||||||
payload = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool can_receive_new_data = (payload.size() > 0 && !m_recv_window.buffer->full());
|
|
||||||
|
|
||||||
if (can_receive_new_data)
|
|
||||||
{
|
{
|
||||||
const size_t nrecv = BAN::Math::min(payload.size(), m_recv_window.buffer->free());
|
auto* buffer = reinterpret_cast<uint8_t*>(m_recv_window.buffer->vaddr());
|
||||||
m_recv_window.buffer->push(payload.slice(0, nrecv));
|
memcpy(buffer + m_recv_window.data_size, payload.data(), payload.size());
|
||||||
|
m_recv_window.data_size += payload.size();
|
||||||
|
|
||||||
epoll_notify(EPOLLIN);
|
epoll_notify(EPOLLIN);
|
||||||
|
|
||||||
dprintln_if(DEBUG_TCP, "Received {} bytes", nrecv);
|
dprintln_if(DEBUG_TCP, "Received {} bytes", payload.size());
|
||||||
}
|
|
||||||
|
|
||||||
// make sure zero window is reported
|
if (m_next_flags == 0)
|
||||||
if (m_last_sent_window_size > 0 && m_recv_window.buffer->full())
|
|
||||||
m_should_send_zero_window = true;
|
|
||||||
else if (can_receive_new_data)
|
|
||||||
{
|
{
|
||||||
m_next_flags = ACK;
|
m_next_flags = ACK;
|
||||||
m_next_state = m_state;
|
m_next_state = m_state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!hungup_before && has_hungup_impl())
|
if (!hungup_before && has_hungup_impl())
|
||||||
epoll_notify(EPOLLHUP);
|
epoll_notify(EPOLLHUP);
|
||||||
|
|
@ -883,14 +793,21 @@ namespace Kernel
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_send_window.current_ack - m_send_window.has_ghost_byte > m_send_window.start_seq)
|
if (m_send_window.data_size > 0 && m_send_window.current_ack - m_send_window.has_ghost_byte > m_send_window.start_seq)
|
||||||
{
|
{
|
||||||
const uint32_t acknowledged_bytes = m_send_window.current_ack - m_send_window.start_seq - m_send_window.has_ghost_byte;
|
uint32_t acknowledged_bytes = m_send_window.current_ack - m_send_window.start_seq - m_send_window.has_ghost_byte;
|
||||||
ASSERT(acknowledged_bytes <= m_send_window.buffer->size());
|
ASSERT(acknowledged_bytes <= m_send_window.data_size);
|
||||||
|
|
||||||
|
m_send_window.data_size -= acknowledged_bytes;
|
||||||
m_send_window.start_seq += acknowledged_bytes;
|
m_send_window.start_seq += acknowledged_bytes;
|
||||||
|
|
||||||
|
if (m_send_window.data_size > 0)
|
||||||
|
{
|
||||||
|
auto* send_buffer = reinterpret_cast<uint8_t*>(m_send_window.buffer->vaddr());
|
||||||
|
memmove(send_buffer, send_buffer + acknowledged_bytes, m_send_window.data_size);
|
||||||
|
}
|
||||||
|
|
||||||
m_send_window.sent_size -= acknowledged_bytes;
|
m_send_window.sent_size -= acknowledged_bytes;
|
||||||
m_send_window.buffer->pop(acknowledged_bytes);
|
|
||||||
|
|
||||||
epoll_notify(EPOLLOUT);
|
epoll_notify(EPOLLOUT);
|
||||||
|
|
||||||
|
|
@ -899,32 +816,26 @@ namespace Kernel
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool should_retransmit = m_send_window.had_zero_window || (m_send_window.sent_size > 0 && current_ms >= m_send_window.last_send_ms + retransmit_timeout_ms);
|
const bool should_retransmit = m_send_window.data_size > 0 && current_ms >= m_send_window.last_send_ms + retransmit_timeout_ms;
|
||||||
|
|
||||||
const bool can_send_new_data = (m_send_window.buffer->size() > m_send_window.sent_size && m_send_window.sent_size < m_send_window.scaled_size());
|
if (m_send_window.data_size > m_send_window.sent_size || should_retransmit)
|
||||||
|
|
||||||
if (m_send_window.scaled_size() > 0 && (should_retransmit || can_send_new_data))
|
|
||||||
{
|
{
|
||||||
m_send_window.had_zero_window = false;
|
|
||||||
|
|
||||||
ASSERT(m_connection_info.has_value());
|
ASSERT(m_connection_info.has_value());
|
||||||
auto* target_address = reinterpret_cast<const sockaddr*>(&m_connection_info->address);
|
auto* target_address = reinterpret_cast<const sockaddr*>(&m_connection_info->address);
|
||||||
auto target_address_len = m_connection_info->address_len;
|
auto target_address_len = m_connection_info->address_len;
|
||||||
|
|
||||||
const size_t send_offset = should_retransmit ? 0 : m_send_window.sent_size;
|
const uint32_t send_base = should_retransmit ? 0 : m_send_window.sent_size;
|
||||||
|
|
||||||
const size_t total_send = BAN::Math::min<size_t>(
|
const uint32_t total_send = BAN::Math::min<uint32_t>(m_send_window.data_size - send_base, m_send_window.scaled_size());
|
||||||
m_send_window.buffer->size() - send_offset,
|
|
||||||
m_send_window.scaled_size() - send_offset
|
|
||||||
);
|
|
||||||
|
|
||||||
m_send_window.current_seq = m_send_window.start_seq + send_offset;
|
m_send_window.current_seq = m_send_window.start_seq + m_send_window.sent_size;
|
||||||
|
|
||||||
for (size_t i = 0; i < total_send;)
|
auto* send_buffer = reinterpret_cast<const uint8_t*>(m_send_window.buffer->vaddr() + send_base);
|
||||||
|
for (uint32_t i = 0; i < total_send;)
|
||||||
{
|
{
|
||||||
const size_t to_send = BAN::Math::min<size_t>(total_send - i, m_send_window.mss);
|
const uint32_t to_send = BAN::Math::min(total_send - i, m_send_window.mss);
|
||||||
|
|
||||||
auto message = m_send_window.buffer->get_data().slice(send_offset + i, to_send);
|
auto message = BAN::ConstByteSpan(send_buffer + i, to_send);
|
||||||
|
|
||||||
m_next_flags = ACK;
|
m_next_flags = ACK;
|
||||||
if (auto ret = m_network_layer.sendto(*this, message, target_address, target_address_len); ret.is_error())
|
if (auto ret = m_network_layer.sendto(*this, message, target_address, target_address_len); ret.is_error())
|
||||||
|
|
@ -935,10 +846,9 @@ namespace Kernel
|
||||||
|
|
||||||
dprintln_if(DEBUG_TCP, "Sent {} bytes", to_send);
|
dprintln_if(DEBUG_TCP, "Sent {} bytes", to_send);
|
||||||
|
|
||||||
i += to_send;
|
m_send_window.sent_size += to_send;
|
||||||
m_send_window.current_seq += to_send;
|
m_send_window.current_seq += to_send;
|
||||||
if (send_offset + i > m_send_window.sent_size)
|
i += to_send;
|
||||||
m_send_window.sent_size = send_offset + i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_send_window.last_send_ms = current_ms;
|
m_send_window.last_send_ms = current_ms;
|
||||||
|
|
@ -946,30 +856,6 @@ namespace Kernel
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_last_sent_window_size == 0)
|
|
||||||
m_should_send_zero_window = false;
|
|
||||||
|
|
||||||
if (m_should_send_zero_window || m_should_send_window_update)
|
|
||||||
{
|
|
||||||
ASSERT(m_connection_info.has_value());
|
|
||||||
auto* target_address = reinterpret_cast<const sockaddr*>(&m_connection_info->address);
|
|
||||||
auto target_address_len = m_connection_info->address_len;
|
|
||||||
|
|
||||||
m_next_flags = ACK;
|
|
||||||
if (auto ret = m_network_layer.sendto(*this, {}, target_address, target_address_len); ret.is_error())
|
|
||||||
dwarnln("{}", ret.error());
|
|
||||||
|
|
||||||
m_should_send_zero_window = false;
|
|
||||||
m_should_send_window_update = false;
|
|
||||||
|
|
||||||
if (m_last_sent_window_size == 0 && !m_recv_window.buffer->full())
|
|
||||||
{
|
|
||||||
m_next_flags = ACK;
|
|
||||||
if (auto ret = m_network_layer.sendto(*this, {}, target_address, target_address_len); ret.is_error())
|
|
||||||
dwarnln("{}", ret.error());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_thread_blocker.unblock();
|
m_thread_blocker.unblock();
|
||||||
m_thread_blocker.block_with_wake_time_ms(current_ms + retransmit_timeout_ms, &m_mutex);
|
m_thread_blocker.block_with_wake_time_ms(current_ms + retransmit_timeout_ms, &m_mutex);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,26 +35,13 @@ namespace Kernel
|
||||||
m_address_len = 0;
|
m_address_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UDPSocket::get_protocol_header(BAN::ByteSpan header_buffer, BAN::ConstByteSpan payload, uint16_t dst_port, PseudoHeader pseudo_header)
|
void UDPSocket::add_protocol_header(BAN::ByteSpan packet, uint16_t dst_port, PseudoHeader)
|
||||||
{
|
{
|
||||||
ASSERT(header_buffer.size() == protocol_header_size());
|
auto& header = packet.as<UDPHeader>();
|
||||||
|
header.src_port = bound_port();
|
||||||
auto& header = header_buffer.as<UDPHeader>();
|
header.dst_port = dst_port;
|
||||||
header = {
|
header.length = packet.size();
|
||||||
.src_port = bound_port(),
|
header.checksum = 0;
|
||||||
.dst_port = dst_port,
|
|
||||||
.length = protocol_header_size() + payload.size(),
|
|
||||||
.checksum = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
const BAN::ConstByteSpan buffers[] {
|
|
||||||
BAN::ConstByteSpan::from(pseudo_header),
|
|
||||||
header_buffer,
|
|
||||||
payload,
|
|
||||||
};
|
|
||||||
header.checksum = calculate_internet_checksum({ buffers, sizeof(buffers) / sizeof(*buffers) });
|
|
||||||
if (header.checksum == 0)
|
|
||||||
header.checksum = 0xFFFF;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UDPSocket::receive_packet(BAN::ConstByteSpan packet, const sockaddr* sender, socklen_t sender_len)
|
void UDPSocket::receive_packet(BAN::ConstByteSpan packet, const sockaddr* sender, socklen_t sender_len)
|
||||||
|
|
@ -225,11 +212,10 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<void> UDPSocket::getsockopt_impl(int level, int option, void* value, socklen_t* value_len)
|
BAN::ErrorOr<void> UDPSocket::getsockopt_impl(int level, int option, void* value, socklen_t* value_len)
|
||||||
{
|
{
|
||||||
int result;
|
if (level != SOL_SOCKET)
|
||||||
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
|
||||||
switch (level)
|
int result;
|
||||||
{
|
|
||||||
case SOL_SOCKET:
|
|
||||||
switch (option)
|
switch (option)
|
||||||
{
|
{
|
||||||
case SO_ERROR:
|
case SO_ERROR:
|
||||||
|
|
@ -242,16 +228,7 @@ namespace Kernel
|
||||||
result = m_packet_buffer->size();
|
result = m_packet_buffer->size();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dwarnln("getsockopt(SOLSOCKET, {})", option);
|
return BAN::Error::from_errno(ENOTSUP);
|
||||||
return BAN::Error::from_errno(ENOPROTOOPT);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case IPPROTO_UDP:
|
|
||||||
dwarnln("getsockopt(IPPROTO_UDP, {})", option);
|
|
||||||
return BAN::Error::from_errno(ENOPROTOOPT);
|
|
||||||
default:
|
|
||||||
dwarnln("getsockopt({}, {})", level, option);
|
|
||||||
return BAN::Error::from_errno(EINVAL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t len = BAN::Math::min<size_t>(sizeof(result), *value_len);
|
const size_t len = BAN::Math::min<size_t>(sizeof(result), *value_len);
|
||||||
|
|
@ -261,27 +238,6 @@ namespace Kernel
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<void> UDPSocket::setsockopt_impl(int level, int option, const void* value, socklen_t value_len)
|
|
||||||
{
|
|
||||||
(void)value;
|
|
||||||
(void)value_len;
|
|
||||||
|
|
||||||
switch (level)
|
|
||||||
{
|
|
||||||
case SOL_SOCKET:
|
|
||||||
dwarnln("setsockopt(SOL_SOCKET, {})", option);
|
|
||||||
return BAN::Error::from_errno(ENOPROTOOPT);
|
|
||||||
case IPPROTO_UDP:
|
|
||||||
dwarnln("setsockopt(IPPROTO_UDP, {})", option);
|
|
||||||
return BAN::Error::from_errno(ENOPROTOOPT);
|
|
||||||
default:
|
|
||||||
dwarnln("setsockopt({}, {})", level, option);
|
|
||||||
return BAN::Error::from_errno(EINVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::ErrorOr<long> UDPSocket::ioctl_impl(int request, void* argument)
|
BAN::ErrorOr<long> UDPSocket::ioctl_impl(int request, void* argument)
|
||||||
{
|
{
|
||||||
switch (request)
|
switch (request)
|
||||||
|
|
|
||||||
|
|
@ -707,10 +707,7 @@ namespace Kernel
|
||||||
BAN::ErrorOr<void> UnixDomainSocket::getsockopt_impl(int level, int option, void* value, socklen_t* value_len)
|
BAN::ErrorOr<void> UnixDomainSocket::getsockopt_impl(int level, int option, void* value, socklen_t* value_len)
|
||||||
{
|
{
|
||||||
if (level != SOL_SOCKET)
|
if (level != SOL_SOCKET)
|
||||||
{
|
|
||||||
dwarnln("getsockopt({}, {})", level, option);
|
|
||||||
return BAN::Error::from_errno(EINVAL);
|
return BAN::Error::from_errno(EINVAL);
|
||||||
}
|
|
||||||
|
|
||||||
int result;
|
int result;
|
||||||
switch (option)
|
switch (option)
|
||||||
|
|
@ -739,10 +736,7 @@ namespace Kernel
|
||||||
BAN::ErrorOr<void> UnixDomainSocket::setsockopt_impl(int level, int option, const void* value, socklen_t value_len)
|
BAN::ErrorOr<void> UnixDomainSocket::setsockopt_impl(int level, int option, const void* value, socklen_t value_len)
|
||||||
{
|
{
|
||||||
if (level != SOL_SOCKET)
|
if (level != SOL_SOCKET)
|
||||||
{
|
|
||||||
dwarnln("setsockopt({}, {})", level, option);
|
|
||||||
return BAN::Error::from_errno(EINVAL);
|
return BAN::Error::from_errno(EINVAL);
|
||||||
}
|
|
||||||
|
|
||||||
switch (option)
|
switch (option)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@
|
||||||
#include <kernel/ELF.h>
|
#include <kernel/ELF.h>
|
||||||
#include <kernel/Epoll.h>
|
#include <kernel/Epoll.h>
|
||||||
#include <kernel/FS/DevFS/FileSystem.h>
|
#include <kernel/FS/DevFS/FileSystem.h>
|
||||||
#include <kernel/FS/EventFD.h>
|
|
||||||
#include <kernel/FS/ProcFS/FileSystem.h>
|
#include <kernel/FS/ProcFS/FileSystem.h>
|
||||||
#include <kernel/FS/VirtualFileSystem.h>
|
#include <kernel/FS/VirtualFileSystem.h>
|
||||||
#include <kernel/IDT.h>
|
#include <kernel/IDT.h>
|
||||||
|
|
@ -29,7 +28,6 @@
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/banan-os.h>
|
#include <sys/banan-os.h>
|
||||||
#include <sys/eventfd.h>
|
|
||||||
#include <sys/futex.h>
|
#include <sys/futex.h>
|
||||||
#include <sys/sysmacros.h>
|
#include <sys/sysmacros.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
|
@ -381,7 +379,7 @@ namespace Kernel
|
||||||
const auto [master_addr, master_size] = master_tls;
|
const auto [master_addr, master_size] = master_tls;
|
||||||
ASSERT(master_size % alignof(uthread) == 0);
|
ASSERT(master_size % alignof(uthread) == 0);
|
||||||
|
|
||||||
const size_t tls_size = master_size + sizeof(uthread);
|
const size_t tls_size = master_size + PAGE_SIZE;
|
||||||
|
|
||||||
auto region = TRY(MemoryBackedRegion::create(
|
auto region = TRY(MemoryBackedRegion::create(
|
||||||
page_table,
|
page_table,
|
||||||
|
|
@ -410,26 +408,28 @@ namespace Kernel
|
||||||
bytes_copied += to_copy;
|
bytes_copied += to_copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto uthread = TRY(BAN::UniqPtr<struct uthread>::create());
|
const uthread uthread {
|
||||||
*uthread = {
|
|
||||||
.self = reinterpret_cast<struct uthread*>(region->vaddr() + master_size),
|
.self = reinterpret_cast<struct uthread*>(region->vaddr() + master_size),
|
||||||
.master_tls_addr = reinterpret_cast<void*>(master_addr),
|
.master_tls_addr = reinterpret_cast<void*>(master_addr),
|
||||||
.master_tls_size = master_size,
|
.master_tls_size = master_size,
|
||||||
.master_tls_module_count = 1,
|
|
||||||
.dynamic_tls = nullptr,
|
|
||||||
.cleanup_stack = nullptr,
|
.cleanup_stack = nullptr,
|
||||||
.id = 0,
|
.id = 0,
|
||||||
.errno_ = 0,
|
.errno_ = 0,
|
||||||
.cancel_type = 0,
|
.cancel_type = 0,
|
||||||
.cancel_state = 0,
|
.cancel_state = 0,
|
||||||
.canceled = 0,
|
.canceled = 0,
|
||||||
.dtv = { 0, region->vaddr() }
|
|
||||||
};
|
};
|
||||||
|
const uintptr_t dtv[2] { 1, region->vaddr() };
|
||||||
|
|
||||||
TRY(region->copy_data_to_region(
|
TRY(region->copy_data_to_region(
|
||||||
master_size,
|
master_size,
|
||||||
reinterpret_cast<const uint8_t*>(uthread.ptr()),
|
reinterpret_cast<const uint8_t*>(&uthread),
|
||||||
sizeof(struct uthread)
|
sizeof(uthread)
|
||||||
|
));
|
||||||
|
TRY(region->copy_data_to_region(
|
||||||
|
master_size + sizeof(uthread),
|
||||||
|
reinterpret_cast<const uint8_t*>(&dtv),
|
||||||
|
sizeof(dtv)
|
||||||
));
|
));
|
||||||
|
|
||||||
TLSResult result;
|
TLSResult result;
|
||||||
|
|
@ -1658,6 +1658,12 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<long> Process::sys_getsockopt(int socket, int level, int option_name, void* user_option_value, socklen_t* user_option_len)
|
BAN::ErrorOr<long> Process::sys_getsockopt(int socket, int level, int option_name, void* user_option_value, socklen_t* user_option_len)
|
||||||
{
|
{
|
||||||
|
if (level != SOL_SOCKET)
|
||||||
|
{
|
||||||
|
dwarnln("{}: getsockopt level {}", name(), level);
|
||||||
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
socklen_t option_len;
|
socklen_t option_len;
|
||||||
TRY(read_from_user(user_option_len, &option_len, sizeof(socklen_t)));
|
TRY(read_from_user(user_option_len, &option_len, sizeof(socklen_t)));
|
||||||
|
|
||||||
|
|
@ -1679,6 +1685,12 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<long> Process::sys_setsockopt(int socket, int level, int option_name, const void* user_option_value, socklen_t option_len)
|
BAN::ErrorOr<long> Process::sys_setsockopt(int socket, int level, int option_name, const void* user_option_value, socklen_t option_len)
|
||||||
{
|
{
|
||||||
|
if (level != SOL_SOCKET)
|
||||||
|
{
|
||||||
|
dwarnln("{}: setsockopt level {}", name(), level);
|
||||||
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
if (option_len < 0)
|
if (option_len < 0)
|
||||||
return BAN::Error::from_errno(EINVAL);
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
|
||||||
|
|
@ -2162,27 +2174,6 @@ namespace Kernel
|
||||||
return TRY(static_cast<Epoll*>(epoll_inode.ptr())->wait(BAN::Span<epoll_event>(events, maxevents), waketime_ns));
|
return TRY(static_cast<Epoll*>(epoll_inode.ptr())->wait(BAN::Span<epoll_event>(events, maxevents), waketime_ns));
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<long> Process::sys_eventfd(unsigned int initval, int flags)
|
|
||||||
{
|
|
||||||
if (flags & ~(EFD_CLOEXEC | EFD_NONBLOCK | EFD_SEMAPHORE))
|
|
||||||
return BAN::Error::from_errno(EINVAL);
|
|
||||||
|
|
||||||
int oflags = 0;
|
|
||||||
if (flags & EFD_CLOEXEC)
|
|
||||||
oflags |= O_CLOEXEC;
|
|
||||||
if (flags & EFD_NONBLOCK)
|
|
||||||
oflags |= O_NONBLOCK;
|
|
||||||
|
|
||||||
const bool is_semaphore = !!(flags & EFD_SEMAPHORE);
|
|
||||||
|
|
||||||
return TRY(m_open_file_descriptors.open(
|
|
||||||
VirtualFileSystem::File {
|
|
||||||
TRY(EventFD::create(initval, is_semaphore)),
|
|
||||||
"<eventfd>"_sv
|
|
||||||
}, oflags
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::ErrorOr<long> Process::sys_pipe(int user_fildes[2])
|
BAN::ErrorOr<long> Process::sys_pipe(int user_fildes[2])
|
||||||
{
|
{
|
||||||
int fildes[2];
|
int fildes[2];
|
||||||
|
|
@ -2380,8 +2371,6 @@ namespace Kernel
|
||||||
TRY(read_string_from_user(user_path, path, PATH_MAX));
|
TRY(read_string_from_user(user_path, path, PATH_MAX));
|
||||||
|
|
||||||
auto new_cwd = TRY(find_file(AT_FDCWD, path, O_SEARCH));
|
auto new_cwd = TRY(find_file(AT_FDCWD, path, O_SEARCH));
|
||||||
if (!new_cwd.inode->mode().ifdir())
|
|
||||||
return BAN::Error::from_errno(ENOTDIR);
|
|
||||||
|
|
||||||
LockGuard _(m_process_lock);
|
LockGuard _(m_process_lock);
|
||||||
m_working_directory = BAN::move(new_cwd);
|
m_working_directory = BAN::move(new_cwd);
|
||||||
|
|
@ -2665,9 +2654,6 @@ namespace Kernel
|
||||||
for (size_t j = 0; j < new_regions.size(); j++)
|
for (size_t j = 0; j < new_regions.size(); j++)
|
||||||
TRY(m_mapped_regions.insert(i + j + 1, BAN::move(new_regions[j])));
|
TRY(m_mapped_regions.insert(i + j + 1, BAN::move(new_regions[j])));
|
||||||
|
|
||||||
while (i + 1 < m_mapped_regions.size() && !m_mapped_regions[i + 1]->overlaps(vaddr, len))
|
|
||||||
i++;
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,9 +73,7 @@ namespace Kernel
|
||||||
: CharacterDevice(mode, uid, gid)
|
: CharacterDevice(mode, uid, gid)
|
||||||
, m_termios(termios)
|
, m_termios(termios)
|
||||||
, m_rdev(next_tty_rdev())
|
, m_rdev(next_tty_rdev())
|
||||||
{
|
{ }
|
||||||
m_output.buffer = MUST(ByteRingBuffer::create(PAGE_SIZE));
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::RefPtr<TTY> TTY::current()
|
BAN::RefPtr<TTY> TTY::current()
|
||||||
{
|
{
|
||||||
|
|
@ -206,7 +204,7 @@ namespace Kernel
|
||||||
}
|
}
|
||||||
case FIONREAD:
|
case FIONREAD:
|
||||||
{
|
{
|
||||||
*static_cast<int*>(argument) = m_output.flush ? m_output.buffer->size() : 0;
|
*static_cast<int*>(argument) = m_output.flush ? m_output.bytes : 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case TIOCGWINSZ:
|
case TIOCGWINSZ:
|
||||||
|
|
@ -234,13 +232,14 @@ namespace Kernel
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const char* ansi_c_str = LibInput::key_to_utf8_ansi(event.key, event.modifier);
|
const char* ansi_c_str = LibInput::key_to_utf8_ansi(event.key, event.modifier);
|
||||||
if (ansi_c_str == nullptr)
|
if (ansi_c_str)
|
||||||
return;
|
{
|
||||||
|
auto* ptr = reinterpret_cast<const uint8_t*>(ansi_c_str);
|
||||||
while (*ansi_c_str)
|
while (*ptr)
|
||||||
handle_input_byte(*ansi_c_str++);
|
handle_input_byte(*ptr++);
|
||||||
after_write();
|
after_write();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TTY::handle_input_byte(uint8_t ch)
|
void TTY::handle_input_byte(uint8_t ch)
|
||||||
{
|
{
|
||||||
|
|
@ -288,7 +287,7 @@ namespace Kernel
|
||||||
|
|
||||||
if (ch == m_termios.c_cc[VKILL] && (m_termios.c_lflag & ECHOK))
|
if (ch == m_termios.c_cc[VKILL] && (m_termios.c_lflag & ECHOK))
|
||||||
{
|
{
|
||||||
while (!m_output.buffer->empty() && m_output.buffer->back() != '\n')
|
while (m_output.bytes > 0 && m_output.buffer[m_output.bytes - 1] != '\n')
|
||||||
do_backspace();
|
do_backspace();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -308,8 +307,12 @@ namespace Kernel
|
||||||
|
|
||||||
// TODO: terminal suspension with VSTOP/VSTART
|
// TODO: terminal suspension with VSTOP/VSTART
|
||||||
|
|
||||||
if (should_append && !m_output.buffer->full())
|
if (should_append)
|
||||||
m_output.buffer->push({ &ch, 1 });
|
{
|
||||||
|
if (m_output.bytes >= m_output.buffer.size())
|
||||||
|
return;
|
||||||
|
m_output.buffer[m_output.bytes++] = ch;
|
||||||
|
}
|
||||||
|
|
||||||
if (should_append && (force_echo || (m_termios.c_lflag & ECHO)))
|
if (should_append && (force_echo || (m_termios.c_lflag & ECHO)))
|
||||||
{
|
{
|
||||||
|
|
@ -347,22 +350,29 @@ namespace Kernel
|
||||||
|
|
||||||
void TTY::do_backspace()
|
void TTY::do_backspace()
|
||||||
{
|
{
|
||||||
if (m_output.buffer->empty())
|
if (m_output.bytes > 0)
|
||||||
return;
|
|
||||||
|
|
||||||
const bool is_caret_notation =
|
|
||||||
(m_output.buffer->back() < 32) ||
|
|
||||||
(m_output.buffer->back() == 127);
|
|
||||||
|
|
||||||
// handle multibyte UTF8
|
|
||||||
while ((m_output.buffer->back() & 0xC0) == 0x80)
|
|
||||||
m_output.buffer->pop_back(1);
|
|
||||||
|
|
||||||
ASSERT(!m_output.buffer->empty());
|
|
||||||
m_output.buffer->pop_back(1);
|
|
||||||
|
|
||||||
if (is_caret_notation)
|
|
||||||
{
|
{
|
||||||
|
uint8_t last = m_output.buffer[m_output.bytes - 1];
|
||||||
|
|
||||||
|
// Multibyte UTF8
|
||||||
|
if ((last & 0xC0) == 0x80)
|
||||||
|
{
|
||||||
|
// NOTE: this should be valid UTF8 since keyboard input already 'validates' it
|
||||||
|
while ((m_output.buffer[m_output.bytes - 1] & 0xC0) == 0x80)
|
||||||
|
{
|
||||||
|
ASSERT(m_output.bytes > 0);
|
||||||
|
m_output.bytes--;
|
||||||
|
}
|
||||||
|
ASSERT(m_output.bytes > 0);
|
||||||
|
m_output.bytes--;
|
||||||
|
putchar('\b');
|
||||||
|
putchar(' ');
|
||||||
|
putchar('\b');
|
||||||
|
}
|
||||||
|
// Caret notation
|
||||||
|
else if (last < 32 || last == 127)
|
||||||
|
{
|
||||||
|
m_output.bytes--;
|
||||||
putchar('\b');
|
putchar('\b');
|
||||||
putchar('\b');
|
putchar('\b');
|
||||||
putchar(' ');
|
putchar(' ');
|
||||||
|
|
@ -370,13 +380,16 @@ namespace Kernel
|
||||||
putchar('\b');
|
putchar('\b');
|
||||||
putchar('\b');
|
putchar('\b');
|
||||||
}
|
}
|
||||||
|
// Ascii
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
m_output.bytes--;
|
||||||
putchar('\b');
|
putchar('\b');
|
||||||
putchar(' ');
|
putchar(' ');
|
||||||
putchar('\b');
|
putchar('\b');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool TTY::putchar(uint8_t ch)
|
bool TTY::putchar(uint8_t ch)
|
||||||
{
|
{
|
||||||
|
|
@ -398,7 +411,7 @@ namespace Kernel
|
||||||
while (!m_output.flush)
|
while (!m_output.flush)
|
||||||
TRY(Thread::current().block_or_eintr_indefinite(m_output.thread_blocker, &m_mutex));
|
TRY(Thread::current().block_or_eintr_indefinite(m_output.thread_blocker, &m_mutex));
|
||||||
|
|
||||||
if (m_output.buffer->empty())
|
if (m_output.bytes == 0)
|
||||||
{
|
{
|
||||||
if (master_has_closed())
|
if (master_has_closed())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -406,19 +419,19 @@ namespace Kernel
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto data = m_output.buffer->get_data();
|
const size_t max_to_copy = BAN::Math::min<size_t>(buffer.size(), m_output.bytes);
|
||||||
|
|
||||||
const size_t max_to_copy = BAN::Math::min<size_t>(buffer.size(), data.size());
|
|
||||||
size_t to_copy = max_to_copy;
|
size_t to_copy = max_to_copy;
|
||||||
if (m_termios.c_lflag & ICANON)
|
if (m_termios.c_lflag & ICANON)
|
||||||
for (to_copy = 1; to_copy < max_to_copy; to_copy++)
|
for (to_copy = 1; to_copy < max_to_copy; to_copy++)
|
||||||
if (data[to_copy - 1] == NL)
|
if (m_output.buffer[to_copy - 1] == NL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
memcpy(buffer.data(), data.data(), to_copy);
|
memcpy(buffer.data(), m_output.buffer.data(), to_copy);
|
||||||
m_output.buffer->pop(to_copy);
|
|
||||||
|
|
||||||
if (m_output.buffer->empty())
|
memmove(m_output.buffer.data(), m_output.buffer.data() + to_copy, m_output.bytes - to_copy);
|
||||||
|
m_output.bytes -= to_copy;
|
||||||
|
|
||||||
|
if (m_output.bytes == 0)
|
||||||
m_output.flush = false;
|
m_output.flush = false;
|
||||||
|
|
||||||
m_output.thread_blocker.unblock();
|
m_output.thread_blocker.unblock();
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
NAME='cairo'
|
NAME='cairo'
|
||||||
VERSION='1.18.4'
|
VERSION='1.18.4'
|
||||||
DOWNLOAD_URL="https://cairographics.org/releases/cairo-$VERSION.tar.xz#445ed8208a6e4823de1226a74ca319d3600e83f6369f99b14265006599c32ccb"
|
DOWNLOAD_URL="https://cairographics.org/releases/cairo-$VERSION.tar.xz#445ed8208a6e4823de1226a74ca319d3600e83f6369f99b14265006599c32ccb"
|
||||||
DEPENDENCIES=('libpng' 'pixman' 'fontconfig' 'glib' 'libX11' 'libXrender' 'libXext')
|
DEPENDENCIES=('libpng' 'pixman' 'fontconfig' 'glib')
|
||||||
CONFIGURE_OPTIONS=(
|
CONFIGURE_OPTIONS=(
|
||||||
'-Dprefix=/usr'
|
'-Dprefix=/usr'
|
||||||
'-Dtests=disabled'
|
'-Dtests=disabled'
|
||||||
|
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
#!/bin/bash ../install.sh
|
|
||||||
|
|
||||||
NAME='dbus'
|
|
||||||
VERSION='1.16.2'
|
|
||||||
DOWNLOAD_URL="https://dbus.freedesktop.org/releases/dbus/dbus-$VERSION.tar.xz#0ba2a1a4b16afe7bceb2c07e9ce99a8c2c3508e5dec290dbb643384bd6beb7e2"
|
|
||||||
DEPENDENCIES=('glib' 'expat')
|
|
||||||
CONFIGURE_OPTIONS=(
|
|
||||||
'-Dprefix=/usr'
|
|
||||||
'-Depoll=disabled' # linux only
|
|
||||||
'-Dintrusive_tests=false'
|
|
||||||
'-Dinstalled_tests=false'
|
|
||||||
'-Dmodular_tests=disabled'
|
|
||||||
)
|
|
||||||
|
|
||||||
configure() {
|
|
||||||
meson setup \
|
|
||||||
--reconfigure \
|
|
||||||
--cross-file "$MESON_CROSS_FILE" \
|
|
||||||
"${CONFIGURE_OPTIONS[@]}" \
|
|
||||||
build || exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
build() {
|
|
||||||
meson compile -C build || exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
install() {
|
|
||||||
meson install --destdir="$BANAN_SYSROOT" -C build || exit 1
|
|
||||||
}
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
diff -ruN dbus-1.16.2/tools/dbus-print-message.c dbus-1.16.2-banan_os/tools/dbus-print-message.c
|
|
||||||
--- dbus-1.16.2/tools/dbus-print-message.c 2025-02-27 18:29:06.000000000 +0200
|
|
||||||
+++ dbus-1.16.2-banan_os/tools/dbus-print-message.c 2026-02-21 23:23:51.987302740 +0200
|
|
||||||
@@ -31,7 +31,9 @@
|
|
||||||
#include <sys/un.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
+#ifndef __banan_os__
|
|
||||||
#include <netinet/ip.h>
|
|
||||||
+#endif
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
diff -ruN expat-2.7.1/configure expat-2.7.1-banan_os/configure
|
|
||||||
--- expat-2.7.1/configure 2025-03-27 21:46:37.000000000 +0200
|
|
||||||
+++ expat-2.7.1-banan_os/configure 2025-08-10 00:50:27.773898797 +0300
|
|
||||||
@@ -6679,6 +6679,10 @@
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ lt_cv_deplibs_check_method=pass_all
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
@@ -12479,6 +12483,16 @@
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ version_type=linux # correct to gnu/linux during the next big refactor
|
|
||||||
+ need_lib_prefix=no
|
|
||||||
+ need_version=no
|
|
||||||
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
|
|
||||||
+ soname_spec='$libname$release$shared_ext$major'
|
|
||||||
+ dynamic_linker="$host_os DynamicLoader.so"
|
|
||||||
+ shlibpath_var=LD_LIBRARY_PATH
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
library_names_spec='$libname$shared_ext'
|
|
||||||
dynamic_linker="$host_os ld.so"
|
|
||||||
@@ -18079,6 +18093,16 @@
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ version_type=linux # correct to gnu/linux during the next big refactor
|
|
||||||
+ need_lib_prefix=no
|
|
||||||
+ need_version=no
|
|
||||||
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
|
|
||||||
+ soname_spec='$libname$release$shared_ext$major'
|
|
||||||
+ dynamic_linker="$host_os DynamicLoader.so"
|
|
||||||
+ shlibpath_var=LD_LIBRARY_PATH
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
library_names_spec='$libname$shared_ext'
|
|
||||||
dynamic_linker="$host_os ld.so"
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
#!/bin/bash ../install.sh
|
|
||||||
|
|
||||||
NAME='fontconfig'
|
|
||||||
VERSION='2.17.1'
|
|
||||||
DOWNLOAD_URL="https://gitlab.freedesktop.org/fontconfig/fontconfig/-/archive/$VERSION/fontconfig-$VERSION.tar.gz#82e73b26adad651b236e5f5d4b3074daf8ff0910188808496326bd3449e5261d"
|
|
||||||
DEPENDENCIES=('harfbuzz' 'freetype' 'expat' 'libiconv')
|
|
||||||
CONFIGURE_OPTIONS=(
|
|
||||||
'-Dprefix=/usr'
|
|
||||||
'-Dtests=disabled'
|
|
||||||
'-Dnls=disabled'
|
|
||||||
)
|
|
||||||
|
|
||||||
configure() {
|
|
||||||
meson setup \
|
|
||||||
--reconfigure \
|
|
||||||
--cross-file "$MESON_CROSS_FILE" \
|
|
||||||
"${CONFIGURE_OPTIONS[@]}" \
|
|
||||||
build || exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
build() {
|
|
||||||
meson compile -C build || exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
install() {
|
|
||||||
meson install --destdir="$BANAN_SYSROOT" -C build || exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
post_install() {
|
|
||||||
pushd .. &>/dev/null
|
|
||||||
|
|
||||||
local font_name='dejavu-fonts-ttf-2.37'
|
|
||||||
|
|
||||||
if [ ! -f "$font_name.tar.bz2" ]; then
|
|
||||||
wget "http://sourceforge.net/projects/dejavu/files/dejavu/2.37/$font_name.tar.bz2" || exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -d "$font_name" ]; then
|
|
||||||
tar xf "$font_name.tar.bz2" || exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
mkdir -p "$BANAN_SYSROOT/usr/share/fonts/TTF" || exit 1
|
|
||||||
cp "$font_name/ttf/"* "$BANAN_SYSROOT/usr/share/fonts/TTF/" || exit 1
|
|
||||||
cp "$font_name/fontconfig/"* "$BANAN_SYSROOT/usr/share/fontconfig/conf.avail/" || exit 1
|
|
||||||
|
|
||||||
popd &>/dev/null
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
#!/bin/bash ../install.sh
|
|
||||||
|
|
||||||
NAME='fribidi'
|
|
||||||
VERSION='1.0.16'
|
|
||||||
DOWNLOAD_URL="https://github.com/fribidi/fribidi/releases/download/v$VERSION/fribidi-$VERSION.tar.xz#1b1cde5b235d40479e91be2f0e88a309e3214c8ab470ec8a2744d82a5a9ea05c"
|
|
||||||
CONFIG_SUB=('config.sub')
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
diff -ruN fribidi-1.0.16/configure fribidi-1.0.16-banan_os/configure
|
|
||||||
--- fribidi-1.0.16/configure 2024-09-25 21:04:21.000000000 +0300
|
|
||||||
+++ fribidi-1.0.16-banan_os/configure 2025-11-05 20:51:12.227775953 +0200
|
|
||||||
@@ -11536,6 +11536,16 @@
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ version_type=linux # correct to gnu/linux during the next big refactor
|
|
||||||
+ need_lib_prefix=no
|
|
||||||
+ need_version=no
|
|
||||||
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
|
|
||||||
+ soname_spec='$libname$release$shared_ext$major'
|
|
||||||
+ dynamic_linker="$host_os DynamicLoader.so"
|
|
||||||
+ shlibpath_var=LD_LIBRARY_PATH
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
library_names_spec='$libname$shared_ext'
|
|
||||||
dynamic_linker="$host_os ld.so"
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
#!/bin/bash ../install.sh
|
|
||||||
|
|
||||||
NAME='gdk-pixbuf'
|
|
||||||
VERSION='2.44.4'
|
|
||||||
DOWNLOAD_URL="https://gitlab.gnome.org/GNOME/gdk-pixbuf/-/archive/$VERSION/gdk-pixbuf-$VERSION.tar.gz#6de2f77d992155b4121d20036e7e986dfe595a0e654381cdd0d7257f493c208a"
|
|
||||||
DEPENDENCIES=('glib' 'libpng' 'libjpeg' 'libtiff' 'shared-mime-info')
|
|
||||||
CONFIGURE_OPTIONS=(
|
|
||||||
'-Dprefix=/usr'
|
|
||||||
'-Dtests=false'
|
|
||||||
'-Dman=false'
|
|
||||||
)
|
|
||||||
|
|
||||||
configure() {
|
|
||||||
meson setup \
|
|
||||||
--reconfigure \
|
|
||||||
--cross-file "$MESON_CROSS_FILE" \
|
|
||||||
"${CONFIGURE_OPTIONS[@]}" \
|
|
||||||
build || exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
build() {
|
|
||||||
meson compile -C build || exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
install() {
|
|
||||||
meson install --destdir="$BANAN_SYSROOT" -C build || exit 1
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +1,13 @@
|
||||||
#!/bin/bash ../install.sh
|
#!/bin/bash ../install.sh
|
||||||
|
|
||||||
NAME='git'
|
NAME='git'
|
||||||
VERSION='2.53.0'
|
VERSION='2.52.0'
|
||||||
DOWNLOAD_URL="https://www.kernel.org/pub/software/scm/git/git-$VERSION.tar.xz#5818bd7d80b061bbbdfec8a433d609dc8818a05991f731ffc4a561e2ca18c653"
|
DOWNLOAD_URL="https://www.kernel.org/pub/software/scm/git/git-$VERSION.tar.xz#3cd8fee86f69a949cb610fee8cd9264e6873d07fa58411f6060b3d62729ed7c5"
|
||||||
DEPENDENCIES=('zlib' 'openssl' 'curl' 'libiconv')
|
DEPENDENCIES=('zlib' 'openssl' 'curl')
|
||||||
CONFIGURE_OPTIONS=(
|
CONFIGURE_OPTIONS=(
|
||||||
'--with-curl'
|
'--with-curl'
|
||||||
'--with-openssl'
|
'--with-openssl'
|
||||||
ac_cv_fread_reads_directories=no
|
ac_cv_fread_reads_directories=no
|
||||||
ac_cv_iconv_omits_bom=no
|
|
||||||
ac_cv_lib_curl_curl_global_init=yes
|
|
||||||
ac_cv_snprintf_returns_bogus=no
|
ac_cv_snprintf_returns_bogus=no
|
||||||
|
ac_cv_lib_curl_curl_global_init=yes
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
#!/bin/bash ../install.sh
|
|
||||||
|
|
||||||
NAME='gtk'
|
|
||||||
VERSION='3.24.49'
|
|
||||||
DOWNLOAD_URL="https://gitlab.gnome.org/GNOME/gtk/-/archive/$VERSION/gtk-$VERSION.tar.gz#a2958d82986c81794e953a3762335fa7c78948706d23cced421f7245ca544cbc"
|
|
||||||
DEPENDENCIES=('glib' 'gdk-pixbuf' 'pango' 'libatk' 'libepoxy' 'libXrandr')
|
|
||||||
CONFIGURE_OPTIONS=(
|
|
||||||
'-Dprefix=/usr'
|
|
||||||
'-Dtests=false'
|
|
||||||
'-Dexamples=false'
|
|
||||||
'-Dintrospection=false'
|
|
||||||
'-Dx11_backend=true'
|
|
||||||
'-Dwayland_backend=false'
|
|
||||||
)
|
|
||||||
|
|
||||||
configure() {
|
|
||||||
meson setup \
|
|
||||||
--reconfigure \
|
|
||||||
--cross-file "$MESON_CROSS_FILE" \
|
|
||||||
"${CONFIGURE_OPTIONS[@]}" \
|
|
||||||
build || exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
build() {
|
|
||||||
meson compile -C build || exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
install() {
|
|
||||||
meson install --destdir="$BANAN_SYSROOT" -C build || exit 1
|
|
||||||
}
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
#!/bin/bash ../install.sh
|
|
||||||
|
|
||||||
NAME='icu'
|
|
||||||
VERSION='78.1'
|
|
||||||
DOWNLOAD_URL="https://github.com/unicode-org/icu/releases/download/release-$VERSION/icu4c-$VERSION-sources.tgz#6217f58ca39b23127605cfc6c7e0d3475fe4b0d63157011383d716cb41617886"
|
|
||||||
TAR_CONTENT='icu'
|
|
||||||
_DEPENDENCIES=('ca-certificates' 'openssl' 'zlib' 'zstd')
|
|
||||||
CONFIG_SUB=('source/config.sub')
|
|
||||||
CONFIGURE_OPTIONS=(
|
|
||||||
"--with-cross-build=$BANAN_PORT_DIR/icu/icu-$VERSION-$BANAN_ARCH/source/build-host"
|
|
||||||
'--disable-tests'
|
|
||||||
'--disable-samples'
|
|
||||||
)
|
|
||||||
|
|
||||||
pre_configure() {
|
|
||||||
unset CC CXX LD AS AR
|
|
||||||
|
|
||||||
mkdir -p source/build-host || exit 1
|
|
||||||
pushd source/build-host || exit 1
|
|
||||||
../configure --disable-tests --disable-samples || exit 1
|
|
||||||
make -j$(proc) || exit 1
|
|
||||||
popd >/dev/null || exit 1
|
|
||||||
|
|
||||||
pushd source >/dev/null || exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
post_configure() {
|
|
||||||
popd >/dev/null || exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
pre_build() {
|
|
||||||
pushd source >/dev/null || exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
post_build() {
|
|
||||||
popd >/dev/null || exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
pre_install() {
|
|
||||||
pushd source >/dev/null || exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
post_install() {
|
|
||||||
popd >/dev/null || exit 1
|
|
||||||
}
|
|
||||||
|
|
@ -1,95 +0,0 @@
|
||||||
diff -ruN icu-78.1/source/config/mh-banan_os icu-78.1-banan_os/source/config/mh-banan_os
|
|
||||||
--- icu-78.1/source/config/mh-banan_os 1970-01-01 02:00:00.000000000 +0200
|
|
||||||
+++ icu-78.1-banan_os/source/config/mh-banan_os 2025-11-06 23:07:11.542495330 +0200
|
|
||||||
@@ -0,0 +1,80 @@
|
|
||||||
+## -*-makefile-*-
|
|
||||||
+## Copyright (C) 2016 and later: Unicode, Inc. and others.
|
|
||||||
+## License & terms of use: http://www.unicode.org/copyright.html
|
|
||||||
+## haiku-specific setup
|
|
||||||
+## Copyright (c) 2010-2012, International Business Machines Corporation and
|
|
||||||
+## others. All Rights Reserved.
|
|
||||||
+##
|
|
||||||
+
|
|
||||||
+## Commands to generate dependency files
|
|
||||||
+GEN_DEPS.c= $(CC) -E -MM $(DEFS) $(CPPFLAGS)
|
|
||||||
+GEN_DEPS.cc= $(CXX) -E -MM $(DEFS) $(CPPFLAGS)
|
|
||||||
+
|
|
||||||
+## Flags for position independent code
|
|
||||||
+SHAREDLIBCFLAGS = -fPIC
|
|
||||||
+SHAREDLIBCXXFLAGS = -fPIC
|
|
||||||
+SHAREDLIBCPPFLAGS = -DPIC
|
|
||||||
+
|
|
||||||
+## Additional flags when building libraries and with threads
|
|
||||||
+LIBCPPFLAGS =
|
|
||||||
+THREADSCPPFLAGS =
|
|
||||||
+
|
|
||||||
+#
|
|
||||||
+CPPFLAGS += -DU_CHARSET_IS_UTF8=1
|
|
||||||
+
|
|
||||||
+## Compiler switch to embed a runtime search path
|
|
||||||
+LD_RPATH=
|
|
||||||
+LD_RPATH_PRE = -Wl,-rpath,
|
|
||||||
+
|
|
||||||
+## Compiler switch to embed a library name
|
|
||||||
+LD_SONAME = -Wl,-soname -Wl,$(notdir $(MIDDLE_SO_TARGET))
|
|
||||||
+
|
|
||||||
+## Shared object suffix
|
|
||||||
+SO = so
|
|
||||||
+## Non-shared intermediate object suffix
|
|
||||||
+STATIC_O = ao
|
|
||||||
+
|
|
||||||
+## Compilation rules
|
|
||||||
+%.$(STATIC_O): $(srcdir)/%.c
|
|
||||||
+ $(COMPILE.c) $(STATICCPPFLAGS) $(STATICCFLAGS) -o $@ $<
|
|
||||||
+%.o: $(srcdir)/%.c
|
|
||||||
+ $(COMPILE.c) $(DYNAMICCPPFLAGS) $(DYNAMICCFLAGS) -o $@ $<
|
|
||||||
+
|
|
||||||
+%.$(STATIC_O): $(srcdir)/%.cpp
|
|
||||||
+ $(COMPILE.cc) $(STATICCPPFLAGS) $(STATICCXXFLAGS) -o $@ $<
|
|
||||||
+%.o: $(srcdir)/%.cpp
|
|
||||||
+ $(COMPILE.cc) $(DYNAMICCPPFLAGS) $(DYNAMICCXXFLAGS) -o $@ $<
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+## Dependency rules
|
|
||||||
+%.d: $(srcdir)/%.c
|
|
||||||
+ @echo "generating dependency information for $<"
|
|
||||||
+ @$(SHELL) -ec '$(GEN_DEPS.c) $< \
|
|
||||||
+ | sed '\''s%\($*\)\.o[ :]*%\1.o $@ : %g'\'' > $@; \
|
|
||||||
+ [ -s $@ ] || rm -f $@'
|
|
||||||
+
|
|
||||||
+%.d: $(srcdir)/%.cpp
|
|
||||||
+ @echo "generating dependency information for $<"
|
|
||||||
+ @$(SHELL) -ec '$(GEN_DEPS.cc) $< \
|
|
||||||
+ | sed '\''s%\($*\)\.o[ :]*%\1.o $@ : %g'\'' > $@; \
|
|
||||||
+ [ -s $@ ] || rm -f $@'
|
|
||||||
+
|
|
||||||
+## Versioned libraries rules
|
|
||||||
+
|
|
||||||
+%.$(SO).$(SO_TARGET_VERSION_MAJOR): %.$(SO).$(SO_TARGET_VERSION)
|
|
||||||
+ $(RM) $@ && ln -s ${<F} $@
|
|
||||||
+%.$(SO): %.$(SO).$(SO_TARGET_VERSION_MAJOR)
|
|
||||||
+ $(RM) $@ && ln -s ${*F}.$(SO).$(SO_TARGET_VERSION) $@
|
|
||||||
+
|
|
||||||
+## Bind internal references
|
|
||||||
+
|
|
||||||
+# LDflags that pkgdata will use
|
|
||||||
+BIR_LDFLAGS= -Wl,-Bsymbolic
|
|
||||||
+
|
|
||||||
+# Dependencies [i.e. map files] for the final library
|
|
||||||
+BIR_DEPS=
|
|
||||||
+
|
|
||||||
+# Use LIBRARY_PATH instead of LD_LIBRARY_PATH
|
|
||||||
+LDLIBRARYPATH_ENVVAR= LIBRARY_PATH
|
|
||||||
+
|
|
||||||
+## End haiku-specific setup
|
|
||||||
diff -ruN icu-78.1/source/configure icu-78.1-banan_os/source/configure
|
|
||||||
--- icu-78.1/source/configure 2025-10-30 19:37:19.000000000 +0200
|
|
||||||
+++ icu-78.1-banan_os/source/configure 2025-11-06 23:06:17.308923216 +0200
|
|
||||||
@@ -5829,6 +5829,7 @@
|
|
||||||
*-apple-darwin*) icu_cv_host_frag=mh-darwin ;;
|
|
||||||
*-*-beos) icu_cv_host_frag=mh-beos ;;
|
|
||||||
*-*-haiku) icu_cv_host_frag=mh-haiku ;;
|
|
||||||
+*-*-banan_os) icu_cv_host_frag=mh-banan_os ;;
|
|
||||||
*-*-irix*) icu_cv_host_frag=mh-irix ;;
|
|
||||||
*-dec-osf*) icu_cv_host_frag=mh-alpha-osf ;;
|
|
||||||
*-*-nto*) icu_cv_host_frag=mh-qnx ;;
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
--- icu/source/common/unicode/ptypes.h 2025-10-30 19:37:19.000000000 +0200
|
|
||||||
+++ icu-78.1-x86_64/source/common/unicode/ptypes.h 2025-11-06 23:12:15.984514832 +0200
|
|
||||||
@@ -56,7 +56,7 @@
|
|
||||||
// implementations (looking at you, Apple, spring 2024) actually do this, so
|
|
||||||
// ICU4C must detect and deal with that.
|
|
||||||
#if !defined(__cplusplus) && !defined(U_IN_DOXYGEN)
|
|
||||||
-# if U_HAVE_CHAR16_T
|
|
||||||
+# if ! U_HAVE_CHAR16_T
|
|
||||||
# include <uchar.h>
|
|
||||||
# else
|
|
||||||
typedef uint16_t char16_t;
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
#!/bin/bash ../install.sh
|
|
||||||
|
|
||||||
NAME='libICE'
|
|
||||||
VERSION='1.1.2'
|
|
||||||
DOWNLOAD_URL="https://www.x.org/releases/individual/lib/libICE-$VERSION.tar.xz#974e4ed414225eb3c716985df9709f4da8d22a67a2890066bc6dfc89ad298625"
|
|
||||||
CONFIG_SUB=('config.sub')
|
|
||||||
DEPENDENCIES=('xorgproto' 'xtrans')
|
|
||||||
CONFIGURE_OPTIONS=(
|
|
||||||
'--enable-shared=yes'
|
|
||||||
'--enable-static=no'
|
|
||||||
)
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
diff -ruN libICE-1.1.2/configure libICE-1.1.2-banan_os/configure
|
|
||||||
--- libICE-1.1.2/configure 2024-12-13 23:40:33.000000000 +0200
|
|
||||||
+++ libICE-1.1.2-banan_os/configure 2025-11-16 23:38:24.456211241 +0200
|
|
||||||
@@ -6464,6 +6464,10 @@
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ lt_cv_deplibs_check_method=pass_all
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
@@ -11969,6 +11973,16 @@
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ version_type=linux # correct to gnu/linux during the next big refactor
|
|
||||||
+ need_lib_prefix=no
|
|
||||||
+ need_version=no
|
|
||||||
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
|
|
||||||
+ soname_spec='$libname$release$shared_ext$major'
|
|
||||||
+ dynamic_linker="$host_os DynamicLoader.so"
|
|
||||||
+ shlibpath_var=LD_LIBRARY_PATH
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
library_names_spec='$libname$shared_ext'
|
|
||||||
dynamic_linker="$host_os ld.so"
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
#!/bin/bash ../install.sh
|
|
||||||
|
|
||||||
NAME='libSM'
|
|
||||||
VERSION='1.2.6'
|
|
||||||
DOWNLOAD_URL="https://www.x.org/releases/individual/lib/libSM-$VERSION.tar.xz#be7c0abdb15cbfd29ac62573c1c82e877f9d4047ad15321e7ea97d1e43d835be"
|
|
||||||
CONFIG_SUB=('config.sub')
|
|
||||||
DEPENDENCIES=('libICE')
|
|
||||||
CONFIGURE_OPTIONS=(
|
|
||||||
'--enable-shared=yes'
|
|
||||||
'--enable-static=no'
|
|
||||||
)
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
diff -ruN libSM-1.2.6/configure libSM-1.2.6-banan_os/configure
|
|
||||||
--- libSM-1.2.6/configure 2025-03-09 03:46:18.000000000 +0200
|
|
||||||
+++ libSM-1.2.6-banan_os/configure 2025-11-16 23:36:16.733929290 +0200
|
|
||||||
@@ -6262,6 +6262,10 @@
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ lt_cv_deplibs_check_method=pass_all
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
@@ -11797,6 +11801,16 @@
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ version_type=linux # correct to gnu/linux during the next big refactor
|
|
||||||
+ need_lib_prefix=no
|
|
||||||
+ need_version=no
|
|
||||||
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
|
|
||||||
+ soname_spec='$libname$release$shared_ext$major'
|
|
||||||
+ dynamic_linker="$host_os DynamicLoader.so"
|
|
||||||
+ shlibpath_var=LD_LIBRARY_PATH
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
library_names_spec='$libname$shared_ext'
|
|
||||||
dynamic_linker="$host_os ld.so"
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
#!/bin/bash ../install.sh
|
|
||||||
|
|
||||||
NAME='libX11'
|
|
||||||
VERSION='1.8.12'
|
|
||||||
DOWNLOAD_URL="https://www.x.org/releases/individual/lib/libX11-$VERSION.tar.xz#fa026f9bb0124f4d6c808f9aef4057aad65e7b35d8ff43951cef0abe06bb9a9a"
|
|
||||||
CONFIG_SUB=('config.sub')
|
|
||||||
DEPENDENCIES=('xorgproto' 'xtrans' 'libxcb')
|
|
||||||
CONFIGURE_OPTIONS=(
|
|
||||||
'--enable-shared=yes'
|
|
||||||
'--enable-static=no'
|
|
||||||
)
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
diff -ruN libX11-1.8.12/configure libX11-1.8.12-banan_os/configure
|
|
||||||
--- libX11-1.8.12/configure 2025-03-09 01:53:09.000000000 +0200
|
|
||||||
+++ libX11-1.8.12-banan_os/configure 2025-11-13 20:07:46.592619585 +0200
|
|
||||||
@@ -6633,6 +6633,10 @@
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ lt_cv_deplibs_check_method=pass_all
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
@@ -12138,6 +12142,16 @@
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ version_type=linux # correct to gnu/linux during the next big refactor
|
|
||||||
+ need_lib_prefix=no
|
|
||||||
+ need_version=no
|
|
||||||
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
|
|
||||||
+ soname_spec='$libname$release$shared_ext$major'
|
|
||||||
+ dynamic_linker="$host_os DynamicLoader.so"
|
|
||||||
+ shlibpath_var=LD_LIBRARY_PATH
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
library_names_spec='$libname$shared_ext'
|
|
||||||
dynamic_linker="$host_os ld.so"
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
#!/bin/bash ../install.sh
|
|
||||||
|
|
||||||
NAME='libXau'
|
|
||||||
VERSION='1.0.12'
|
|
||||||
DOWNLOAD_URL="https://www.x.org/releases/individual/lib/libXau-$VERSION.tar.xz#74d0e4dfa3d39ad8939e99bda37f5967aba528211076828464d2777d477fc0fb"
|
|
||||||
CONFIG_SUB=('config.sub')
|
|
||||||
DEPENDENCIES=('xorgproto')
|
|
||||||
CONFIGURE_OPTIONS=(
|
|
||||||
'--enable-shared=yes'
|
|
||||||
'--enable-static=no'
|
|
||||||
)
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
diff -ruN libXau-1.0.12/configure libXau-1.0.12-banan_os/configure
|
|
||||||
--- libXau-1.0.12/configure 2024-12-14 03:33:02.000000000 +0200
|
|
||||||
+++ libXau-1.0.12-banan_os/configure 2025-11-13 20:00:35.574268731 +0200
|
|
||||||
@@ -6224,6 +6224,10 @@
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ lt_cv_deplibs_check_method=pass_all
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
@@ -12060,6 +12064,16 @@
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ version_type=linux # correct to gnu/linux during the next big refactor
|
|
||||||
+ need_lib_prefix=no
|
|
||||||
+ need_version=no
|
|
||||||
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
|
|
||||||
+ soname_spec='$libname$release$shared_ext$major'
|
|
||||||
+ dynamic_linker="$host_os DynamicLoader.so"
|
|
||||||
+ shlibpath_var=LD_LIBRARY_PATH
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
library_names_spec='$libname$shared_ext'
|
|
||||||
dynamic_linker="$host_os ld.so"
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
#!/bin/bash ../install.sh
|
|
||||||
|
|
||||||
NAME='libXaw'
|
|
||||||
VERSION='1.0.16'
|
|
||||||
DOWNLOAD_URL="https://www.x.org/releases/individual/lib/libXaw-$VERSION.tar.xz#731d572b54c708f81e197a6afa8016918e2e06dfd3025e066ca642a5b8c39c8f"
|
|
||||||
CONFIG_SUB=('config.sub')
|
|
||||||
DEPENDENCIES=('libX11' 'libXext' 'libXt' 'libXmu' 'libXpm')
|
|
||||||
CONFIGURE_OPTIONS=(
|
|
||||||
'--enable-shared=yes'
|
|
||||||
'--enable-static=no'
|
|
||||||
)
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
diff -ruN libXaw-1.0.16/configure libXaw-1.0.16-banan_os/configure
|
|
||||||
--- libXaw-1.0.16/configure 2024-03-10 19:39:54.000000000 +0200
|
|
||||||
+++ libXaw-1.0.16-banan_os/configure 2025-11-16 23:51:15.704550082 +0200
|
|
||||||
@@ -5977,6 +5977,10 @@
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ lt_cv_deplibs_check_method=pass_all
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
@@ -11343,6 +11347,16 @@
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ version_type=linux # correct to gnu/linux during the next big refactor
|
|
||||||
+ need_lib_prefix=no
|
|
||||||
+ need_version=no
|
|
||||||
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
|
|
||||||
+ soname_spec='$libname$release$shared_ext$major'
|
|
||||||
+ dynamic_linker="$host_os DynamicLoader.so"
|
|
||||||
+ shlibpath_var=LD_LIBRARY_PATH
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
library_names_spec='$libname$shared_ext'
|
|
||||||
dynamic_linker="$host_os ld.so"
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
#!/bin/bash ../install.sh
|
|
||||||
|
|
||||||
NAME='libXdmcp'
|
|
||||||
VERSION='1.1.5'
|
|
||||||
DOWNLOAD_URL="https://www.x.org/releases/individual/lib/libXdmcp-$VERSION.tar.xz#d8a5222828c3adab70adf69a5583f1d32eb5ece04304f7f8392b6a353aa2228c"
|
|
||||||
CONFIG_SUB=('config.sub')
|
|
||||||
DEPENDENCIES=('xorgproto')
|
|
||||||
CONFIGURE_OPTIONS=(
|
|
||||||
'--enable-shared=yes'
|
|
||||||
'--enable-static=no'
|
|
||||||
)
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
diff -ruN libXdmcp-1.1.5/configure libXdmcp-1.1.5-banan_os/configure
|
|
||||||
--- libXdmcp-1.1.5/configure 2024-03-02 23:37:19.000000000 +0200
|
|
||||||
+++ libXdmcp-1.1.5-banan_os/configure 2025-11-13 21:49:06.142805910 +0200
|
|
||||||
@@ -6247,6 +6247,10 @@
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ lt_cv_deplibs_check_method=pass_all
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
@@ -11960,6 +11964,16 @@
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ version_type=linux # correct to gnu/linux during the next big refactor
|
|
||||||
+ need_lib_prefix=no
|
|
||||||
+ need_version=no
|
|
||||||
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
|
|
||||||
+ soname_spec='$libname$release$shared_ext$major'
|
|
||||||
+ dynamic_linker="$host_os DynamicLoader.so"
|
|
||||||
+ shlibpath_var=LD_LIBRARY_PATH
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
library_names_spec='$libname$shared_ext'
|
|
||||||
dynamic_linker="$host_os ld.so"
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
#!/bin/bash ../install.sh
|
|
||||||
|
|
||||||
NAME='libXext'
|
|
||||||
VERSION='1.3.6'
|
|
||||||
DOWNLOAD_URL="https://www.x.org/releases/individual/lib/libXext-$VERSION.tar.xz#edb59fa23994e405fdc5b400afdf5820ae6160b94f35e3dc3da4457a16e89753"
|
|
||||||
CONFIG_SUB=('config.sub')
|
|
||||||
DEPENDENCIES=('libX11')
|
|
||||||
CONFIGURE_OPTIONS=(
|
|
||||||
'--enable-shared=yes'
|
|
||||||
'--enable-static=no'
|
|
||||||
'--disable-malloc0returnsnull'
|
|
||||||
)
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
diff -ruN libXext-1.3.6/configure libXext-1.3.6-banan_os/configure
|
|
||||||
--- libXext-1.3.6/configure 2024-02-04 23:42:50.000000000 +0200
|
|
||||||
+++ libXext-1.3.6-banan_os/configure 2025-11-16 23:30:16.532954111 +0200
|
|
||||||
@@ -6282,6 +6282,10 @@
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ lt_cv_deplibs_check_method=pass_all
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
@@ -11663,6 +11667,16 @@
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
+
|
|
||||||
+banan_os*)
|
|
||||||
+ version_type=linux # correct to gnu/linux during the next big refactor
|
|
||||||
+ need_lib_prefix=no
|
|
||||||
+ need_version=no
|
|
||||||
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
|
|
||||||
+ soname_spec='$libname$release$shared_ext$major'
|
|
||||||
+ dynamic_linker="$host_os DynamicLoader.so"
|
|
||||||
+ shlibpath_var=LD_LIBRARY_PATH
|
|
||||||
+ ;;
|
|
||||||
|
|
||||||
beos*)
|
|
||||||
library_names_spec='$libname$shared_ext'
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
#!/bin/bash ../install.sh
|
|
||||||
|
|
||||||
NAME='libXfixes'
|
|
||||||
VERSION='6.0.2'
|
|
||||||
DOWNLOAD_URL="https://www.x.org/releases/individual/lib/libXfixes-$VERSION.tar.xz#39f115d72d9c5f8111e4684164d3d68cc1fd21f9b27ff2401b08fddfc0f409ba"
|
|
||||||
CONFIG_SUB=('config.sub')
|
|
||||||
DEPENDENCIES=('libX11')
|
|
||||||
CONFIGURE_OPTIONS=(
|
|
||||||
'--enable-shared=yes'
|
|
||||||
'--enable-static=no'
|
|
||||||
)
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
diff -ruN libXfixes-6.0.2/configure libXfixes-6.0.2-banan_os/configure
|
|
||||||
--- libXfixes-6.0.2/configure 2025-09-02 02:25:56.000000000 +0300
|
|
||||||
+++ libXfixes-6.0.2-banan_os/configure 2025-11-16 23:59:00.284383978 +0200
|
|
||||||
@@ -6157,6 +6157,10 @@
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ lt_cv_deplibs_check_method=pass_all
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
@@ -11692,6 +11696,16 @@
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ version_type=linux # correct to gnu/linux during the next big refactor
|
|
||||||
+ need_lib_prefix=no
|
|
||||||
+ need_version=no
|
|
||||||
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
|
|
||||||
+ soname_spec='$libname$release$shared_ext$major'
|
|
||||||
+ dynamic_linker="$host_os DynamicLoader.so"
|
|
||||||
+ shlibpath_var=LD_LIBRARY_PATH
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
library_names_spec='$libname$shared_ext'
|
|
||||||
dynamic_linker="$host_os ld.so"
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
#!/bin/bash ../install.sh
|
|
||||||
|
|
||||||
NAME='libXfont2'
|
|
||||||
VERSION='2.0.7'
|
|
||||||
DOWNLOAD_URL="https://www.x.org/releases/individual/lib/libXfont2-$VERSION.tar.xz#8b7b82fdeba48769b69433e8e3fbb984a5f6bf368b0d5f47abeec49de3e58efb"
|
|
||||||
CONFIG_SUB=('config.sub')
|
|
||||||
DEPENDENCIES=('freetype' 'xorgproto' 'xtrans' 'libfontenc')
|
|
||||||
CONFIGURE_OPTIONS=(
|
|
||||||
'--enable-shared=yes'
|
|
||||||
'--enable-static=no'
|
|
||||||
)
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
diff -ruN libXfont2-2.0.7/configure libXfont2-2.0.7-banan_os/configure
|
|
||||||
--- libXfont2-2.0.7/configure 2024-08-02 02:38:54.000000000 +0300
|
|
||||||
+++ libXfont2-2.0.7-banan_os/configure 2025-11-13 20:21:21.333718050 +0200
|
|
||||||
@@ -6558,6 +6558,10 @@
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ lt_cv_deplibs_check_method=pass_all
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
@@ -11940,6 +11944,16 @@
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ version_type=linux # correct to gnu/linux during the next big refactor
|
|
||||||
+ need_lib_prefix=no
|
|
||||||
+ need_version=no
|
|
||||||
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
|
|
||||||
+ soname_spec='$libname$release$shared_ext$major'
|
|
||||||
+ dynamic_linker="$host_os DynamicLoader.so"
|
|
||||||
+ shlibpath_var=LD_LIBRARY_PATH
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
library_names_spec='$libname$shared_ext'
|
|
||||||
dynamic_linker="$host_os ld.so"
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
#!/bin/bash ../install.sh
|
|
||||||
|
|
||||||
NAME='libXft'
|
|
||||||
VERSION='2.3.9'
|
|
||||||
DOWNLOAD_URL="https://www.x.org/releases/individual/lib/libXft-$VERSION.tar.xz#60a25b78945ed6932635b3bb1899a517d31df7456e69867ffba27f89ff3976f5"
|
|
||||||
CONFIG_SUB=('config.sub')
|
|
||||||
DEPENDENCIES=('libXrender' 'libX11' 'freetype' 'fontconfig')
|
|
||||||
CONFIGURE_OPTIONS=(
|
|
||||||
'--enable-shared=yes'
|
|
||||||
'--enable-static=no'
|
|
||||||
)
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
diff -ruN libXft-2.3.9/configure libXft-2.3.9-banan_os/configure
|
|
||||||
--- libXft-2.3.9/configure 2025-04-20 18:10:46.000000000 +0300
|
|
||||||
+++ libXft-2.3.9-banan_os/configure 2025-11-17 01:42:42.971908492 +0200
|
|
||||||
@@ -5873,6 +5873,10 @@
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ lt_cv_deplibs_check_method=pass_all
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
@@ -11239,6 +11243,16 @@
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ version_type=linux # correct to gnu/linux during the next big refactor
|
|
||||||
+ need_lib_prefix=no
|
|
||||||
+ need_version=no
|
|
||||||
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
|
|
||||||
+ soname_spec='$libname$release$shared_ext$major'
|
|
||||||
+ dynamic_linker="$host_os DynamicLoader.so"
|
|
||||||
+ shlibpath_var=LD_LIBRARY_PATH
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
library_names_spec='$libname$shared_ext'
|
|
||||||
dynamic_linker="$host_os ld.so"
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
#!/bin/bash ../install.sh
|
|
||||||
|
|
||||||
NAME='libXi'
|
|
||||||
VERSION='1.8.2'
|
|
||||||
DOWNLOAD_URL="https://www.x.org/releases/individual/lib/libXi-$VERSION.tar.xz#d0e0555e53d6e2114eabfa44226ba162d2708501a25e18d99cfb35c094c6c104"
|
|
||||||
CONFIG_SUB=('config.sub')
|
|
||||||
DEPENDENCIES=('libX11' 'libXext' 'libXfixes')
|
|
||||||
CONFIGURE_OPTIONS=(
|
|
||||||
'--enable-shared=yes'
|
|
||||||
'--enable-static=no'
|
|
||||||
'--disable-malloc0returnsnull'
|
|
||||||
)
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
diff -ruN libXi-1.8.2/configure libXi-1.8.2-banan_os/configure
|
|
||||||
--- libXi-1.8.2/configure 2024-09-05 04:19:46.000000000 +0300
|
|
||||||
+++ libXi-1.8.2-banan_os/configure 2025-11-16 23:54:14.061298859 +0200
|
|
||||||
@@ -6020,6 +6020,10 @@
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ lt_cv_deplibs_check_method=pass_all
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
@@ -11377,6 +11381,16 @@
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ version_type=linux # correct to gnu/linux during the next big refactor
|
|
||||||
+ need_lib_prefix=no
|
|
||||||
+ need_version=no
|
|
||||||
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
|
|
||||||
+ soname_spec='$libname$release$shared_ext$major'
|
|
||||||
+ dynamic_linker="$host_os DynamicLoader.so"
|
|
||||||
+ shlibpath_var=LD_LIBRARY_PATH
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
library_names_spec='$libname$shared_ext'
|
|
||||||
dynamic_linker="$host_os ld.so"
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
#!/bin/bash ../install.sh
|
|
||||||
|
|
||||||
NAME='libXmu'
|
|
||||||
VERSION='1.2.1'
|
|
||||||
DOWNLOAD_URL="https://www.x.org/releases/individual/lib/libXmu-$VERSION.tar.xz#fcb27793248a39e5fcc5b9c4aec40cc0734b3ca76aac3d7d1c264e7f7e14e8b2"
|
|
||||||
CONFIG_SUB=('config.sub')
|
|
||||||
DEPENDENCIES=('libXt' 'libXext' 'libX11')
|
|
||||||
CONFIGURE_OPTIONS=(
|
|
||||||
'--enable-shared=yes'
|
|
||||||
'--enable-static=no'
|
|
||||||
)
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
diff -ruN libXmu-1.2.1/configure libXmu-1.2.1-banan_os/configure
|
|
||||||
--- libXmu-1.2.1/configure 2024-04-16 23:02:25.000000000 +0300
|
|
||||||
+++ libXmu-1.2.1-banan_os/configure 2025-11-16 23:42:28.961754856 +0200
|
|
||||||
@@ -6165,6 +6165,10 @@
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ lt_cv_deplibs_check_method=pass_all
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
@@ -11492,6 +11496,16 @@
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ version_type=linux # correct to gnu/linux during the next big refactor
|
|
||||||
+ need_lib_prefix=no
|
|
||||||
+ need_version=no
|
|
||||||
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
|
|
||||||
+ soname_spec='$libname$release$shared_ext$major'
|
|
||||||
+ dynamic_linker="$host_os DynamicLoader.so"
|
|
||||||
+ shlibpath_var=LD_LIBRARY_PATH
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
library_names_spec='$libname$shared_ext'
|
|
||||||
dynamic_linker="$host_os ld.so"
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
#!/bin/bash ../install.sh
|
|
||||||
|
|
||||||
NAME='libXpm'
|
|
||||||
VERSION='3.5.17'
|
|
||||||
DOWNLOAD_URL="https://www.x.org/releases/individual/lib/libXpm-$VERSION.tar.xz#64b31f81019e7d388c822b0b28af8d51c4622b83f1f0cb6fa3fc95e271226e43"
|
|
||||||
CONFIG_SUB=('config.sub')
|
|
||||||
DEPENDENCIES=('libX11')
|
|
||||||
CONFIGURE_OPTIONS=(
|
|
||||||
'--enable-shared=yes'
|
|
||||||
'--enable-static=no'
|
|
||||||
)
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
diff -ruN libXpm-3.5.17/configure libXpm-3.5.17-banan_os/configure
|
|
||||||
--- libXpm-3.5.17/configure 2023-10-03 19:12:11.000000000 +0300
|
|
||||||
+++ libXpm-3.5.17-banan_os/configure 2025-11-16 23:46:08.171880860 +0200
|
|
||||||
@@ -5897,6 +5897,10 @@
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ lt_cv_deplibs_check_method=pass_all
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
@@ -11254,6 +11258,16 @@
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ version_type=linux # correct to gnu/linux during the next big refactor
|
|
||||||
+ need_lib_prefix=no
|
|
||||||
+ need_version=no
|
|
||||||
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
|
|
||||||
+ soname_spec='$libname$release$shared_ext$major'
|
|
||||||
+ dynamic_linker="$host_os DynamicLoader.so"
|
|
||||||
+ shlibpath_var=LD_LIBRARY_PATH
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
library_names_spec='$libname$shared_ext'
|
|
||||||
dynamic_linker="$host_os ld.so"
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
#!/bin/bash ../install.sh
|
|
||||||
|
|
||||||
NAME='libXrandr'
|
|
||||||
VERSION='1.5.5'
|
|
||||||
DOWNLOAD_URL="https://xorg.freedesktop.org/archive/individual/lib/libXrandr-$VERSION.tar.xz#72b922c2e765434e9e9f0960148070bd4504b288263e2868a4ccce1b7cf2767a"
|
|
||||||
CONFIG_SUB=('config.sub')
|
|
||||||
DEPENDENCIES=('libX11' 'libXext' 'libXrender')
|
|
||||||
CONFIGURE_OPTIONS=(
|
|
||||||
'--enable-shared=yes'
|
|
||||||
'--enable-static=no'
|
|
||||||
)
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
diff -ruN libXrandr-1.5.5/configure libXrandr-1.5.5-banan_os/configure
|
|
||||||
--- libXrandr-1.5.5/configure 2026-01-26 02:25:38.000000000 +0200
|
|
||||||
+++ libXrandr-1.5.5-banan_os/configure 2026-02-21 23:34:03.906187857 +0200
|
|
||||||
@@ -6162,6 +6162,10 @@
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ lt_cv_deplibs_check_method=pass_all
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
@@ -11697,6 +11701,16 @@
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ version_type=linux # correct to gnu/linux during the next big refactor
|
|
||||||
+ need_lib_prefix=no
|
|
||||||
+ need_version=no
|
|
||||||
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
|
|
||||||
+ soname_spec='$libname$release$shared_ext$major'
|
|
||||||
+ dynamic_linker="$host_os DynamicLoader.so"
|
|
||||||
+ shlibpath_var=LD_LIBRARY_PATH
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
library_names_spec='$libname$shared_ext'
|
|
||||||
dynamic_linker="$host_os ld.so"
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
#!/bin/bash ../install.sh
|
|
||||||
|
|
||||||
NAME='libXrender'
|
|
||||||
VERSION='0.9.12'
|
|
||||||
DOWNLOAD_URL="https://www.x.org/releases/individual/lib/libXrender-$VERSION.tar.xz#b832128da48b39c8d608224481743403ad1691bf4e554e4be9c174df171d1b97"
|
|
||||||
CONFIG_SUB=('config.sub')
|
|
||||||
DEPENDENCIES=('libX11')
|
|
||||||
CONFIGURE_OPTIONS=(
|
|
||||||
'--enable-shared=yes'
|
|
||||||
'--enable-static=no'
|
|
||||||
)
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
diff -ruN libXrender-0.9.12/configure libXrender-0.9.12-banan_os/configure
|
|
||||||
--- libXrender-0.9.12/configure 2024-12-13 23:07:57.000000000 +0200
|
|
||||||
+++ libXrender-0.9.12-banan_os/configure 2025-11-17 00:04:56.995318198 +0200
|
|
||||||
@@ -6035,6 +6035,10 @@
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ lt_cv_deplibs_check_method=pass_all
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
@@ -11570,6 +11574,16 @@
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ version_type=linux # correct to gnu/linux during the next big refactor
|
|
||||||
+ need_lib_prefix=no
|
|
||||||
+ need_version=no
|
|
||||||
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
|
|
||||||
+ soname_spec='$libname$release$shared_ext$major'
|
|
||||||
+ dynamic_linker="$host_os DynamicLoader.so"
|
|
||||||
+ shlibpath_var=LD_LIBRARY_PATH
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
library_names_spec='$libname$shared_ext'
|
|
||||||
dynamic_linker="$host_os ld.so"
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
#!/bin/bash ../install.sh
|
|
||||||
|
|
||||||
NAME='libXt'
|
|
||||||
VERSION='1.3.1'
|
|
||||||
DOWNLOAD_URL="https://www.x.org/releases/individual/lib/libXt-$VERSION.tar.xz#e0a774b33324f4d4c05b199ea45050f87206586d81655f8bef4dba434d931288"
|
|
||||||
CONFIG_SUB=('config.sub')
|
|
||||||
DEPENDENCIES=('libSM' 'libICE' 'libX11')
|
|
||||||
CONFIGURE_OPTIONS=(
|
|
||||||
'--enable-shared=yes'
|
|
||||||
'--enable-static=no'
|
|
||||||
)
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
diff -ruN libXt-1.3.1/configure libXt-1.3.1-banan_os/configure
|
|
||||||
--- libXt-1.3.1/configure 2024-11-17 06:44:13.000000000 +0200
|
|
||||||
+++ libXt-1.3.1-banan_os/configure 2025-11-16 23:33:28.525874895 +0200
|
|
||||||
@@ -6313,6 +6313,10 @@
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ lt_cv_deplibs_check_method=pass_all
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
@@ -11695,6 +11699,16 @@
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ version_type=linux # correct to gnu/linux during the next big refactor
|
|
||||||
+ need_lib_prefix=no
|
|
||||||
+ need_version=no
|
|
||||||
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
|
|
||||||
+ soname_spec='$libname$release$shared_ext$major'
|
|
||||||
+ dynamic_linker="$host_os DynamicLoader.so"
|
|
||||||
+ shlibpath_var=LD_LIBRARY_PATH
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
library_names_spec='$libname$shared_ext'
|
|
||||||
dynamic_linker="$host_os ld.so"
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
#!/bin/bash ../install.sh
|
|
||||||
|
|
||||||
NAME='libXtst'
|
|
||||||
VERSION='1.2.5'
|
|
||||||
DOWNLOAD_URL="https://xorg.freedesktop.org/archive/individual/lib/libXtst-$VERSION.tar.xz#b50d4c25b97009a744706c1039c598f4d8e64910c9fde381994e1cae235d9242"
|
|
||||||
CONFIG_SUB=('config.sub')
|
|
||||||
DEPENDENCIES=('libX11' 'libXext' 'libXi')
|
|
||||||
CONFIGURE_OPTIONS=(
|
|
||||||
'--enable-shared=yes'
|
|
||||||
'--enable-static=no'
|
|
||||||
)
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
diff -ruN libXtst-1.2.5/configure libXtst-1.2.5-banan_os/configure
|
|
||||||
--- libXtst-1.2.5/configure 2024-08-02 03:27:45.000000000 +0300
|
|
||||||
+++ libXtst-1.2.5-banan_os/configure 2026-02-21 23:29:27.999396388 +0200
|
|
||||||
@@ -6194,6 +6194,10 @@
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ lt_cv_deplibs_check_method=pass_all
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
@@ -11606,6 +11610,16 @@
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ version_type=linux # correct to gnu/linux during the next big refactor
|
|
||||||
+ need_lib_prefix=no
|
|
||||||
+ need_version=no
|
|
||||||
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
|
|
||||||
+ soname_spec='$libname$release$shared_ext$major'
|
|
||||||
+ dynamic_linker="$host_os DynamicLoader.so"
|
|
||||||
+ shlibpath_var=LD_LIBRARY_PATH
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
library_names_spec='$libname$shared_ext'
|
|
||||||
dynamic_linker="$host_os ld.so"
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
#!/bin/bash ../install.sh
|
|
||||||
|
|
||||||
NAME='libatk'
|
|
||||||
VERSION='2.56.6'
|
|
||||||
DOWNLOAD_URL="https://gitlab.gnome.org/GNOME/at-spi2-core/-/archive/$VERSION/at-spi2-core-$VERSION.tar.gz#49b1a640d50a95389a31672a0a077f0c20e8e222322cbd0228d3fa597686819d"
|
|
||||||
TAR_CONTENT="at-spi2-core-$VERSION"
|
|
||||||
DEPENDENCIES=('glib' 'dbus' 'libxml2' 'libX11' 'libXtst')
|
|
||||||
CONFIGURE_OPTIONS=(
|
|
||||||
'-Dprefix=/usr'
|
|
||||||
)
|
|
||||||
|
|
||||||
configure() {
|
|
||||||
meson setup \
|
|
||||||
--reconfigure \
|
|
||||||
--cross-file "$MESON_CROSS_FILE" \
|
|
||||||
"${CONFIGURE_OPTIONS[@]}" \
|
|
||||||
build || exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
build() {
|
|
||||||
meson compile -C build || exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
install() {
|
|
||||||
meson install --destdir="$BANAN_SYSROOT" -C build || exit 1
|
|
||||||
}
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
#!/bin/bash ../install.sh
|
|
||||||
|
|
||||||
NAME='libepoxy'
|
|
||||||
VERSION='1.5.10'
|
|
||||||
DOWNLOAD_URL="https://download.gnome.org/sources/libepoxy/1.5/libepoxy-$VERSION.tar.xz#072cda4b59dd098bba8c2363a6247299db1fa89411dc221c8b81b8ee8192e623"
|
|
||||||
DEPENDENCIES=('mesa' 'libX11')
|
|
||||||
CONFIGURE_OPTIONS=(
|
|
||||||
'-Dprefix=/usr'
|
|
||||||
'-Dtests=false'
|
|
||||||
'-Degl=no'
|
|
||||||
)
|
|
||||||
|
|
||||||
configure() {
|
|
||||||
meson setup \
|
|
||||||
--reconfigure \
|
|
||||||
--cross-file "$MESON_CROSS_FILE" \
|
|
||||||
"${CONFIGURE_OPTIONS[@]}" \
|
|
||||||
build || exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
build() {
|
|
||||||
meson compile -C build || exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
install() {
|
|
||||||
meson install --destdir="$BANAN_SYSROOT" -C build || exit 1
|
|
||||||
}
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
--- libepoxy-1.5.10/src/dispatch_common.c 2022-02-17 14:56:12.000000000 +0200
|
|
||||||
+++ libepoxy-1.5.10-banan_os/src/dispatch_common.c 2025-11-11 18:35:23.194563757 +0200
|
|
||||||
@@ -164,7 +164,9 @@
|
|
||||||
#include <windows.h>
|
|
||||||
#else
|
|
||||||
#include <dlfcn.h>
|
|
||||||
+#ifndef __banan_os__
|
|
||||||
#include <err.h>
|
|
||||||
+#endif
|
|
||||||
#include <pthread.h>
|
|
||||||
#endif
|
|
||||||
#include <string.h>
|
|
||||||
@@ -306,8 +308,10 @@
|
|
||||||
pthread_mutex_lock(&api.mutex);
|
|
||||||
if (!*handle) {
|
|
||||||
int flags = RTLD_LAZY | RTLD_LOCAL;
|
|
||||||
+#ifdef RTLD_NOLOAD
|
|
||||||
if (!load)
|
|
||||||
flags |= RTLD_NOLOAD;
|
|
||||||
+#endif
|
|
||||||
|
|
||||||
*handle = dlopen(lib_name, flags);
|
|
||||||
if (!*handle) {
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
#!/bin/bash ../install.sh
|
|
||||||
|
|
||||||
NAME='libfontenc'
|
|
||||||
VERSION='1.1.8'
|
|
||||||
DOWNLOAD_URL="https://www.x.org/releases/individual/lib/libfontenc-$VERSION.tar.xz#7b02c3d405236e0d86806b1de9d6868fe60c313628b38350b032914aa4fd14c6"
|
|
||||||
CONFIG_SUB=('config.sub')
|
|
||||||
DEPENDENCIES=('zlib' 'xorgproto')
|
|
||||||
CONFIGURE_OPTIONS=(
|
|
||||||
'--enable-shared=yes'
|
|
||||||
'--enable-static=no'
|
|
||||||
)
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
diff -ruN libfontenc-1.1.8/configure libfontenc-1.1.8-banan_os/configure
|
|
||||||
--- libfontenc-1.1.8/configure 2024-03-02 20:32:14.000000000 +0200
|
|
||||||
+++ libfontenc-1.1.8-banan_os/configure 2025-11-13 20:25:22.782104114 +0200
|
|
||||||
@@ -6145,6 +6145,10 @@
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ lt_cv_deplibs_check_method=pass_all
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
@@ -11527,6 +11531,16 @@
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ version_type=linux # correct to gnu/linux during the next big refactor
|
|
||||||
+ need_lib_prefix=no
|
|
||||||
+ need_version=no
|
|
||||||
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
|
|
||||||
+ soname_spec='$libname$release$shared_ext$major'
|
|
||||||
+ dynamic_linker="$host_os DynamicLoader.so"
|
|
||||||
+ shlibpath_var=LD_LIBRARY_PATH
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
library_names_spec='$libname$shared_ext'
|
|
||||||
dynamic_linker="$host_os ld.so"
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
#!/bin/bash ../install.sh
|
|
||||||
|
|
||||||
NAME='libpthread-stubs'
|
|
||||||
VERSION='0.5'
|
|
||||||
DOWNLOAD_URL="https://www.x.org/releases/individual/lib/libpthread-stubs-$VERSION.tar.xz#59da566decceba7c2a7970a4a03b48d9905f1262ff94410a649224e33d2442bc"
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
#!/bin/bash ../install.sh
|
|
||||||
|
|
||||||
NAME='libxcb'
|
|
||||||
VERSION='1.17.0'
|
|
||||||
DOWNLOAD_URL="https://www.x.org/releases/individual/lib/libxcb-$VERSION.tar.xz#599ebf9996710fea71622e6e184f3a8ad5b43d0e5fa8c4e407123c88a59a6d55"
|
|
||||||
CONFIG_SUB=('config.sub' 'build-aux/config.sub')
|
|
||||||
DEPENDENCIES=('xcb-proto' 'libXau' 'libXdmcp' 'libpthread-stubs')
|
|
||||||
CONFIGURE_OPTIONS=(
|
|
||||||
'--enable-shared=yes'
|
|
||||||
'--enable-static=no'
|
|
||||||
)
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
diff -ruN libxcb-1.17.0/configure libxcb-1.17.0-banan_os/configure
|
|
||||||
--- libxcb-1.17.0/configure 2024-04-15 18:09:34.000000000 +0300
|
|
||||||
+++ libxcb-1.17.0-banan_os/configure 2025-11-13 19:58:33.829610129 +0200
|
|
||||||
@@ -6886,6 +6886,10 @@
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ lt_cv_deplibs_check_method=pass_all
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
@@ -12538,6 +12542,16 @@
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ version_type=linux # correct to gnu/linux during the next big refactor
|
|
||||||
+ need_lib_prefix=no
|
|
||||||
+ need_version=no
|
|
||||||
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
|
|
||||||
+ soname_spec='$libname$release$shared_ext$major'
|
|
||||||
+ dynamic_linker="$host_os DynamicLoader.so"
|
|
||||||
+ shlibpath_var=LD_LIBRARY_PATH
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
library_names_spec='$libname$shared_ext'
|
|
||||||
dynamic_linker="$host_os ld.so"
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
#!/bin/bash ../install.sh
|
|
||||||
|
|
||||||
NAME='libxkbfile'
|
|
||||||
VERSION='1.1.3'
|
|
||||||
DOWNLOAD_URL="https://www.x.org/releases/individual/lib/libxkbfile-$VERSION.tar.xz#a9b63eea997abb9ee6a8b4fbb515831c841f471af845a09de443b28003874bec"
|
|
||||||
CONFIG_SUB=('config.sub')
|
|
||||||
DEPENDENCIES=('libX11' 'xkeyboard-config')
|
|
||||||
CONFIGURE_OPTIONS=(
|
|
||||||
'--enable-shared=yes'
|
|
||||||
'--enable-static=no'
|
|
||||||
)
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
diff -ruN libxkbfile-1.1.3/configure libxkbfile-1.1.3-banan_os/configure
|
|
||||||
--- libxkbfile-1.1.3/configure 2024-02-05 00:14:27.000000000 +0200
|
|
||||||
+++ libxkbfile-1.1.3-banan_os/configure 2025-11-13 20:14:55.314294954 +0200
|
|
||||||
@@ -5944,6 +5944,10 @@
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ lt_cv_deplibs_check_method=pass_all
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
lt_cv_deplibs_check_method=pass_all
|
|
||||||
;;
|
|
||||||
@@ -11356,6 +11360,16 @@
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
|
|
||||||
+banan_os*)
|
|
||||||
+ version_type=linux # correct to gnu/linux during the next big refactor
|
|
||||||
+ need_lib_prefix=no
|
|
||||||
+ need_version=no
|
|
||||||
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
|
|
||||||
+ soname_spec='$libname$release$shared_ext$major'
|
|
||||||
+ dynamic_linker="$host_os DynamicLoader.so"
|
|
||||||
+ shlibpath_var=LD_LIBRARY_PATH
|
|
||||||
+ ;;
|
|
||||||
+
|
|
||||||
beos*)
|
|
||||||
library_names_spec='$libname$shared_ext'
|
|
||||||
dynamic_linker="$host_os ld.so"
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue