-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a66b4bb
commit 2a36484
Showing
19 changed files
with
4,342 additions
and
191 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
app-objs := httpserver.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
alloc | ||
paging | ||
net | ||
multitask |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
/* Copyright (c) [2023] [Syswonder Community] | ||
* [Ruxos] is licensed under Mulan PSL v2. | ||
* You can use this software according to the terms and conditions of the Mulan PSL v2. | ||
* You may obtain a copy of Mulan PSL v2 at: | ||
* http://license.coscl.org.cn/MulanPSL2 | ||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. | ||
* See the Mulan PSL v2 for more details. | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <unistd.h> | ||
#include <pthread.h> | ||
#include <arpa/inet.h> | ||
#include <sys/socket.h> | ||
|
||
#define PORT 5555 | ||
#define BUFFER_SIZE 1024 | ||
|
||
void *handle_client(void *arg) { | ||
int new_socket = *(int*)arg; | ||
char buffer[BUFFER_SIZE] = {0}; | ||
|
||
read(new_socket, buffer, BUFFER_SIZE); | ||
printf("Server received: %s\n", buffer); | ||
send(new_socket, "Hello from server", strlen("Hello from server"), 0); | ||
printf("Server sent: %s\n", "Hello from server"); | ||
|
||
close(new_socket); | ||
free(arg); // Free the allocated memory for the socket | ||
|
||
return NULL; | ||
} | ||
|
||
void *server_thread(void *arg) { | ||
int server_fd, *new_socket; | ||
struct sockaddr_in address; | ||
int addrlen = sizeof(address); | ||
|
||
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { | ||
perror("Socket failed"); | ||
exit(EXIT_FAILURE); | ||
} | ||
|
||
address.sin_family = AF_INET; | ||
address.sin_addr.s_addr = INADDR_ANY; | ||
address.sin_port = htons(PORT); | ||
|
||
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { | ||
perror("Bind failed"); | ||
close(server_fd); | ||
exit(EXIT_FAILURE); | ||
} | ||
|
||
if (listen(server_fd, 3) < 0) { | ||
perror("Listen failed"); | ||
close(server_fd); | ||
exit(EXIT_FAILURE); | ||
} | ||
|
||
printf("Server listening on 127.0.0.1:%d\n", PORT); | ||
|
||
while (1) { | ||
new_socket = malloc(sizeof(int)); | ||
if ((*new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) { | ||
perror("Accept failed"); | ||
free(new_socket); | ||
continue; | ||
} | ||
|
||
pthread_t client_thread; | ||
if (pthread_create(&client_thread, NULL, handle_client, new_socket) != 0) { | ||
perror("Failed to create client thread"); | ||
free(new_socket); | ||
} | ||
} | ||
|
||
close(server_fd); | ||
|
||
return NULL; | ||
} | ||
|
||
void *client_thread(void *arg) { | ||
sleep(1); // Ensure the server is listening before the client tries to connect | ||
|
||
struct sockaddr_in serv_addr; | ||
char *message = "Hello from client"; | ||
char buffer[BUFFER_SIZE] = {0}; | ||
int sock = 0; | ||
|
||
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { | ||
perror("Socket creation error"); | ||
return NULL; | ||
} | ||
|
||
serv_addr.sin_family = AF_INET; | ||
serv_addr.sin_port = htons(PORT); | ||
|
||
if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) { | ||
perror("Invalid address / Address not supported"); | ||
close(sock); | ||
return NULL; | ||
} | ||
|
||
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { | ||
perror("Connection failed"); | ||
close(sock); | ||
return NULL; | ||
} | ||
|
||
send(sock, message, strlen(message), 0); | ||
printf("Client sent: %s\n", message); | ||
read(sock, buffer, BUFFER_SIZE); | ||
printf("Client received: %s\n", buffer); | ||
|
||
close(sock); | ||
|
||
return NULL; | ||
} | ||
|
||
int main() { | ||
pthread_t server_tid, client_tid; | ||
|
||
if (pthread_create(&server_tid, NULL, server_thread, NULL) != 0) { | ||
perror("Failed to create server thread"); | ||
exit(EXIT_FAILURE); | ||
} | ||
|
||
if (pthread_create(&client_tid, NULL, client_thread, NULL) != 0) { | ||
perror("Failed to create client thread"); | ||
exit(EXIT_FAILURE); | ||
} | ||
|
||
pthread_join(server_tid, NULL); | ||
pthread_join(client_tid, NULL); | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
/* Copyright (c) [2023] [Syswonder Community] | ||
* [Ruxos] is licensed under Mulan PSL v2. | ||
* You can use this software according to the terms and conditions of the Mulan PSL v2. | ||
* You may obtain a copy of Mulan PSL v2 at: | ||
* http://license.coscl.org.cn/MulanPSL2 | ||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. | ||
* See the Mulan PSL v2 for more details. | ||
*/ | ||
use crate::{EthernetAddress, NetBuf, NetBufBox, NetBufPool, NetBufPtr, NetDriverOps}; | ||
use alloc::collections::VecDeque; | ||
use alloc::sync::Arc; | ||
use driver_common::{BaseDriverOps, DevError, DevResult, DeviceType}; | ||
|
||
extern crate alloc; | ||
|
||
const NET_BUF_LEN: usize = 1526; | ||
|
||
/// The VirtIO network device driver. | ||
/// | ||
/// `QS` is the VirtIO queue size. | ||
pub struct LoopbackDevice { | ||
mac_address: EthernetAddress, | ||
pub(crate) queue: VecDeque<NetBufBox>, | ||
buf_pool: Arc<NetBufPool>, | ||
} | ||
|
||
unsafe impl Send for LoopbackDevice {} | ||
unsafe impl Sync for LoopbackDevice {} | ||
|
||
impl LoopbackDevice { | ||
/// Creates a new driver instance and initializes the device | ||
pub fn new(mac_address: [u8; 6]) -> Self { | ||
let buf_pool = match NetBufPool::new(1024, NET_BUF_LEN) { | ||
Ok(pool) => pool, | ||
Err(_) => { | ||
panic!("fail to create netbufpool"); | ||
} | ||
}; | ||
Self { | ||
mac_address: EthernetAddress(mac_address), | ||
queue: VecDeque::new(), | ||
buf_pool: buf_pool, | ||
} | ||
} | ||
} | ||
|
||
impl BaseDriverOps for LoopbackDevice { | ||
fn device_name(&self) -> &str { | ||
"loopback" | ||
} | ||
|
||
fn device_type(&self) -> DeviceType { | ||
DeviceType::Net | ||
} | ||
} | ||
|
||
impl NetDriverOps for LoopbackDevice { | ||
#[inline] | ||
fn mac_address(&self) -> EthernetAddress { | ||
EthernetAddress(self.mac_address.0) | ||
} | ||
|
||
#[inline] | ||
fn can_transmit(&self) -> bool { | ||
true | ||
} | ||
|
||
#[inline] | ||
fn can_receive(&self) -> bool { | ||
!self.queue.is_empty() | ||
} | ||
|
||
#[inline] | ||
fn rx_queue_size(&self) -> usize { | ||
self.queue.len() | ||
} | ||
|
||
#[inline] | ||
fn tx_queue_size(&self) -> usize { | ||
self.queue.len() | ||
} | ||
|
||
fn fill_rx_buffers(&mut self, buf_pool: &Arc<NetBufPool>) -> DevResult { | ||
Ok(()) | ||
} | ||
|
||
fn recycle_rx_buffer(&mut self, rx_buf: NetBufPtr) -> DevResult { | ||
unsafe { self.queue.push_back(NetBuf::from_buf_ptr(rx_buf)) } | ||
Ok(()) | ||
} | ||
|
||
fn recycle_tx_buffers(&mut self) -> DevResult { | ||
Ok(()) | ||
} | ||
|
||
fn prepare_tx_buffer(&self, tx_buf: &mut NetBuf, pkt_len: usize) -> DevResult { | ||
Ok(()) | ||
} | ||
|
||
fn transmit(&mut self, tx_buf: NetBufPtr) -> DevResult { | ||
unsafe { self.queue.push_back(NetBuf::from_buf_ptr(tx_buf)) } | ||
Ok(()) | ||
} | ||
|
||
fn receive(&mut self) -> DevResult<NetBufPtr> { | ||
if let Some(token) = self.queue.pop_front() { | ||
Ok(token.into_buf_ptr()) | ||
} else { | ||
Err(DevError::Again) | ||
} | ||
} | ||
|
||
fn alloc_tx_buffer(&mut self, size: usize) -> DevResult<NetBufPtr> { | ||
let mut net_buf = self.buf_pool.alloc_boxed().ok_or(DevError::NoMemory)?; | ||
let pkt_len = size; | ||
|
||
// 1. Check if the buffer is large enough. | ||
let hdr_len = net_buf.header_len(); | ||
if hdr_len + pkt_len > net_buf.capacity() { | ||
return Err(DevError::InvalidParam); | ||
} | ||
net_buf.set_packet_len(pkt_len); | ||
|
||
// 2. Return the buffer. | ||
Ok(net_buf.into_buf_ptr()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.