📄 proxy.c
字号:
}
/**********************************************/
int add_ips_to_shok(shok *theShok, unsigned int fromIP, unsigned int toIP, int withSib)
{
add_ip_to_list(&(theShok->ips), toIP);
if (withSib)
add_ip_to_list(&(theShok->sib->ips), toIP);
return 1;
}
/**********************************************/
int make_udp_port_pair(unsigned int fromIP, unsigned int toIP, shok **rtpSocket, shok **rtcpSocket, const int CPUNR)
{
shok *theShok;
KRTSPROXYD_OUT(KERN_INFO "MAKE_UDP_PORT_PAIR from %x to %x\n", fromIP, toIP);
if ((theShok = find_available_shok(fromIP, toIP, 1, CPUNR)) != NULL) {
add_ips_to_shok(theShok, fromIP, toIP, 1);
}
else {
theShok = make_new_shok(fromIP, toIP, 1, CPUNR);
}
if (theShok && theShok->sib) {
*rtpSocket = theShok;
*rtcpSocket = theShok->sib;
return 1;
}
else
return -1;
}
int has_content_length(char *inp, int *len)
{
int l;
char *p;
l = strlen(inp);
if (l < 16) /* "Content-Length:n" (16) */
return 0;
if (strn_casecmp(inp, "content-length", 14) != 0)
return 0;
p = strchr(inp, ':');
p++;
while (*p && (*p == ' '))
p++;
if (p) {
*len = atoi(p);
return 1;
}
else
return 0;
}
int has_sessionID(char *inp, char *sessionID)
{
int l;
char *p;
l = strlen(inp);
if (l < 9) /* "Session:x" (9) */
return 0;
if (strn_casecmp(inp, "session", 7) != 0)
return 0;
p = strchr(inp, ':');
p++;
while (*p && (*p == ' '))
p++;
if (p) {
strcpy(sessionID, p);
return 1;
}
else
return 0;
}
int upon_receipt_from(shok *theShok, int fromIP, do_routine doThis, void *withThis)
{
ipList *listEl;
KRTSPROXYD_OUT(KERN_INFO "UPON_RECEIPT_FROM %x\n", fromIP);
listEl = find_ip_in_list(theShok->ips, fromIP);
if (!listEl)
return -1;
listEl->what_to_do = doThis;
listEl->what_to_do_it_with = withThis;
return 0;
}
/**********************************************/
int has_IN_IP(char *inp, char *str)
{
int l;
char *p;
l = strlen(inp);
if (l < 10) /* "c=IN IP4 n" (10) */
return 0;
if (strn_casecmp(inp, "c=IN IP4 ", 9) != 0)
return 0;
p = inp + 9;
while (*p && (*p == ' '))
p++;
while (*p && ((*p >= '0' && *p <= '9') || *p == '.'))
*str++ = *p++;
*str = '\0';
return 1;
}
char *source_eq_string(char *inp)
{
int l;
char *p;
l = strlen(inp);
if (l < 7) /* source= */
return NULL;
p = inp;
while (p) {
p = strchr(p, '=');
if (p - 6 < inp) {
p++;
continue;
}
if (strn_casecmp(&p[-6], "source=", 7) != 0) {
p++;
continue;
}
return &p[-6];
}
return NULL;
}
int transfer_data(void *refCon, char *buf, int bufSize)
{
trans_pb *tpb = (trans_pb*)refCon;
int ret = 0;
int isRTCP = 0;
struct sockaddr_in sin;
if (!tpb)
return -1;
sin.sin_family = AF_INET;
sin.sin_port = htons(tpb->send_to_port);
sin.sin_addr.s_addr = tpb->send_to_ip;
if (strstr(tpb->socketName,"RTCP"))
{
isRTCP = 1;
}
ret = UdpSendBuffer(tpb->send_from->socket, buf, bufSize, O_NONBLOCK, (struct sockaddr *)&sin, sizeof(sin));
KRTSPROXYD_OUT(KERN_INFO "Sent %d bytes to %s on port %d\n", ret, ntoa(tpb->send_to_ip), tpb->send_to_port);
return ret;
}
int has_ports(char *inp, unsigned int *client_port, unsigned int *server_port)
{
int l, got_server = 0, got_client = 0;
char *p;
l = strlen(inp);
if (l < 40) /* "Transport:<>client_port=n-nserver_port=n-n" (40) */
return 0;
if (strn_casecmp(inp, "transport", 9) != 0)
return 0;
p = inp;
while (p && !(got_client && got_server)) {
p = strchr(p, '=');
if (p - 11 < inp) {
}
else if (strn_casecmp(&p[-11], "client_port=", 12) == 0) {
got_client = 1;
*client_port = atoi(&p[1]);
}
else if (strn_casecmp(&p[-11], "server_port=", 12) == 0) {
got_server = 1;
*server_port = atoi(&p[1]);
}
p++;
}
if (got_client && got_server)
return 1;
else
return 0;
}
int connect_to_address(struct socket *skt, unsigned int address, unsigned port)
{
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(port); //fixme?
sin.sin_addr.s_addr = address; //already network byte order!!
KRTSPROXYD_OUT(KERN_INFO "connect to server-addr:port %s, %d\n",ntoa(address),port);
return skt->ops->connect(skt, (struct sockaddr*)&sin, sizeof(sin), 0);
}
/*
* Send a datagram to a given address. We move the address into kernel
* space and check the user space data area is readable before invoking
* the protocol.
*/
int UdpSendBuffer(struct socket *sock, void * buff, size_t len, unsigned flags,
struct sockaddr *addr, int addr_len)
{
int err = -1;
struct msghdr msg;
struct iovec iov;
mm_segment_t oldfs;
if (!sock)
goto out;
iov.iov_base=buff;
iov.iov_len=len;
msg.msg_name=0;
msg.msg_iov=&iov;
msg.msg_iovlen=1;
msg.msg_control=NULL;
msg.msg_controllen=0;
msg.msg_namelen=0;
msg.msg_name=(void *)addr;
msg.msg_namelen=(__kernel_size_t)addr_len;
msg.msg_flags = MSG_DONTWAIT;
oldfs = get_fs(); set_fs(KERNEL_DS);
err = sock_sendmsg(sock, &msg, len);
set_fs(oldfs);
out:
return err;
}
/**********************************************/
int remove_shok(shok *theShok, int withSib, const int CPUNR)
{
shok *cur = NULL, *last;
//shok *curSib = NULL;
cur = threadinfo[CPUNR].gShokQueue;
if (cur == theShok) {
threadinfo[CPUNR].gShokQueue = cur->next;
goto doSib;
}
last = cur;
cur = cur->next;
while (cur) {
if (cur == theShok) {
last->next = cur->next;
goto doSib;
}
last = cur;
cur = cur->next;
}
return 0;
doSib:
if (cur->sib)
cur->sib->sib = NULL;
if (withSib && cur->sib)
remove_shok(cur->sib, 0, CPUNR);
{
ipList *ipn, *ipl = cur->ips;
while (ipl) {
ipn = ipl->next;
kfree(ipn);
ipl = ipn;
}
}
sock_release(cur->socket);
kfree(cur);
return 1;
}
/**********************************************/
int remove_ip_from_list(ipList **list, int ip)
{
ipList *last, *theEl = *list;
if (theEl->ip == ip) { //fix me!! nbo or hbo?
*list = theEl->next;
kfree(theEl);
return 1;
}
last = theEl;
theEl = theEl->next;
while (theEl) {
if (theEl->ip == ip) {
last->next = theEl->next;
kfree(theEl);
return 1;
}
last = theEl;
theEl = theEl->next;
}
return 0;
}
/**********************************************/
void remove_shok_ref(shok *theShok, unsigned int fromIP, unsigned int toIP, int withSib, const int CPUNR)
{
remove_ip_from_list(&(theShok->ips), toIP);
if (withSib)
remove_ip_from_list(&(theShok->sib->ips), toIP);
if (theShok->sib->ips == NULL)
remove_shok(theShok->sib, 0, CPUNR);
if (theShok->ips == NULL)
remove_shok(theShok, 0, CPUNR);
}
/*
* Receive a frame from the socket and optionally record the address of the
* sender. We verify the buffers are writable and if needed move the
* sender address from kernel to user space.
*/
int UdpReceiveBuffer(struct socket *sock, void * ubuf, size_t size, unsigned flags, struct sockaddr *addr, int *addr_len)
{
struct iovec iov;
struct msghdr msg;
char address[MAX_SOCK_ADDR];
int err = -1;
mm_segment_t oldfs;
if (!sock)
goto out;
msg.msg_control=NULL;
msg.msg_controllen=0;
msg.msg_iovlen=1;
msg.msg_iov=&iov;
iov.iov_len=(size_t)(size-1);
iov.iov_base=(void *)ubuf;
msg.msg_name= address;
msg.msg_namelen= MAX_SOCK_ADDR;
msg.msg_flags = 0;
oldfs = get_fs(); set_fs(KERNEL_DS);
err = sock_recvmsg(sock, &msg, size-1, MSG_DONTWAIT);
set_fs(oldfs);
if(err >= 0)
{
memcpy((void *)addr, (void *)address, *addr_len);
KRTSPROXYD_OUT(KERN_INFO "the FromIP is %s\n", ntoa(((struct sockaddr_in *)addr)->sin_addr.s_addr));
}
out:
return err;
}
/**********************************************/
rtsp_session *new_session(void)
{
rtsp_session *s;
int i;
s = (rtsp_session*)kmalloc(sizeof(rtsp_session), GFP_KERNEL);
if (s) {
s->next = NULL;
s->die = 0; //false
s->client_skt = NULL;
s->new_session = 1;
s->client_ip = (unsigned int)0xFFFFFFFF; //255.255.255.255 invalid address
s->server_address = NULL;
s->server_skt = NULL;
s->server_ip = (unsigned int)0xFFFFFFFF;
s->server_port = 554;
s->server_skt_pending_connection = 0;//false
s->state = stRecvClientCommand; //initialize the status
s->transaction_type = ttNone;
s->sessionID = NULL;
s->cur_trk = 0;
for (i=0; i<MX_TRACKS; i++) {
s->trk[i].ID = 0;
s->trk[i].ClientRTPPort = (unsigned short)0xFFFF;
s->trk[i].ServerRTPPort = (unsigned short)0xFFFF;
s->trk[i].RTP_S2P = NULL;
s->trk[i].RTCP_S2P = NULL;
s->trk[i].RTP_P2C = NULL;
s->trk[i].RTCP_P2C = NULL;
s->trk[i].RTP_S2C_tpb.status = NULL;
s->trk[i].RTP_S2C_tpb.send_from = NULL;
s->trk[i].RTP_S2C_tpb.send_to_ip = (unsigned int)0xFFFFFFFF;
s->trk[i].RTP_S2C_tpb.send_to_port = (unsigned short)0xFFFF;
s->trk[i].RTP_S2C_tpb.packetSendCount = 0;
s->trk[i].RTP_S2C_tpb.nextDropPacket = 0;
s->trk[i].RTP_S2C_tpb.droppedPacketCount = 0;
s->trk[i].RTCP_S2C_tpb.status = NULL;
s->trk[i].RTCP_S2C_tpb.send_from = NULL;
s->trk[i].RTCP_S2C_tpb.send_to_ip = (unsigned int)0xFFFFFFFF;
s->trk[i].RTCP_S2C_tpb.send_to_port = (unsigned short)0xFFFF;
s->trk[i].RTCP_S2C_tpb.packetSendCount = 0;
s->trk[i].RTCP_S2C_tpb.nextDropPacket = 0;
s->trk[i].RTCP_S2C_tpb.droppedPacketCount = 0;
s->trk[i].RTCP_C2S_tpb.status = NULL;
s->trk[i].RTCP_C2S_tpb.send_from = NULL;
s->trk[i].RTCP_C2S_tpb.send_to_ip = (unsigned int)0xFFFFFFFF;
s->trk[i].RTCP_C2S_tpb.send_to_port = (unsigned short)0xFFFF;
s->trk[i].RTCP_C2S_tpb.packetSendCount = 0;
s->trk[i].RTCP_C2S_tpb.nextDropPacket = 0;
s->trk[i].RTCP_C2S_tpb.droppedPacketCount = 0;
}
s->numTracks = 0;
//init buffers
s->cinbuf = (char*)get_free_page((int)GFP_KERNEL);
if (s->cinbuf == NULL)
{
KRTSPROXYD_OUT(KERN_CRIT "kRtspProxyd: Not enough memory for basic needs\n");
return NULL;
}
s->coutbuf = (char*)get_free_page((int)GFP_KERNEL);
if (s->coutbuf == NULL)
{
KRTSPROXYD_OUT(KERN_CRIT "kRtspProxyd: Not enough memory for basic needs\n");
free_page((unsigned long)s->cinbuf);
return NULL;
}
s->sinbuf = (char*)get_free_page((int)GFP_KERNEL);
if (s->sinbuf == NULL)
{
KRTSPROXYD_OUT(KERN_CRIT "kRtspProxyd: Not enough memory for basic needs\n");
free_page((unsigned long)s->cinbuf);
free_page((unsigned long)s->coutbuf);
return NULL;
}
s->soutbuf = (char*)get_free_page((int)GFP_KERNEL);
if (s->soutbuf == NULL)
{
KRTSPROXYD_OUT(KERN_CRIT "kRtspProxyd: Not enough memory for basic needs\n");
free_page((unsigned long)s->cinbuf);
free_page((unsigned long)s->coutbuf);
free_page((unsigned long)s->sinbuf);
return NULL;
}
s->amtInClientInBuffer = 0;
s->amtInClientOutBuffer = 0;
s->amtInServerInBuffer = 0;
s->amtInServerOutBuffer = 0;
s->totalContentLength = 0; // headers + body
s->contentLength = 0; // just body
s->haveParsedServerReplyHeaders = 0;
}
return s;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -